你的心如利箭 在风中笔直的飞翔
github DNS ALEXA CDN
jquery JS CSS CSS3 HTML5 svg php --- isux w3cplus

21270

  博客园  :: 首页  ::  ::  ::  :: 管理

 代码: 两列图片瀑布流(一次后台取数据,无ajax,图片懒加载。下拉后分批显示图片。图片高度未知,当图片onload后才显示容器)

 

【思路】:

图片瀑布流,网上代码有多种实现方式,也有各类插件。没找到合意的,所以根据网上找的一段代码,进行了较大改动。

需引用 zepto 或 jquery。

我这个是应用于手机上的,两列瀑布流,图片高度未知——等图片的onloaded事件触发后,才对容器进行计算和定位。

大容器是 $("#imgList"),容器格子是$(".pin")

初始状态下,php一次性生成全部容器格子的数据(大约几十个吧。因为瀑布流不可能是无限制瀑布流,适可而止的呈献给用户合适数量的图片就足以满足需求了),不采用ajax。这样代码存在于真实的网页源码中,也适合seo。后台也不必单独开发接口,易于管理。

$(this.aPin).addClass("hide").addClass("l");//初始化:先一次性将所有容器格子设为隐藏+左浮动

滚动后触发事件,只有容器格子中的图片被加载后,容器格子才会移除隐藏状态

之后计算左列和右列已有的高度(图片未载入完毕的容器格子为隐藏状态,不计算),每一个新的容器格子,都追加到当前最短的一列。也就是添加样式 .l  或 .r

WATERFALL.Timer :说一下这个定时器。图片的onloaded事件会触发很多次,为了避免载入每张图片后,都将页面重绘计算一次,所以加了个定时器作限制。(100毫秒后如无新图载入,调用计算页面位置的方法;有新图载入,仅仅只刷新定时器)

 

其它参数可参考.js文件页头注释

下面先谈一下scroll事件,后面再给出正式代码。


 

 

前言:我们先看一下scroll事件,调用得太频繁了 (chrome中打开,用鼠标拉一下滚动条,看一下控制台)

<p>拿鼠标拖动一下滚动条,看看scroll事件触发的有多么频繁</p>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><hr>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><hr>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><hr>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><hr>
<script src="http://cdn.bootcss.com/zepto/1.1.6/zepto.min.js"></script>
<script type="text/javascript">
$(function(){
    var WATERFALL = {
        scroll:function() {//发生滚动后,调用此方法
            var curTime=new Date().getTime();
            console.log(curTime);
        },
    };

//------------------------正文--------------------------
    //滚屏
    $(window).scroll(function() {
        WATERFALL.scroll('#imgList','.pin');
    });

});
</script>

所以需要对滚屏事件加一下限制:(增加了一个变量logTime,记载上一次滚动请求的时间)   (这种废弃,用下面那个)

    var WATERFALL = {
        logTime:0,//最后一次滚屏操作的时间
        checkscroll:function() {
            //两次滚动请求之间时间需大于500毫秒,避免多次请求
            var curTime=new Date().getTime();
            if(this.logTime > (curTime-500) ){
                return false;
            }else{
                this.logTime = curTime;
                return true;
            }
        },
        scroll:function() {//发生滚动后,调用此方法
            if(this.checkscroll()){
                var curTime=new Date().getTime();
                console.log(curTime);
            }
        },

    };

又一种降低频繁请求的写法:2015-11-19 

<script type="text/javascript" src="http://cdn.bootcss.com/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
    var timer;
    $(window).scroll(function () {
        clearTimeout(timer);
        timer = setTimeout(function () {
            console.log(new Date().getTime());
            console.log($(document).scrollTop());
        }, 100);
    });
});
</script>

 

 


 

正式代码:

1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>图片瀑布流</title>
    <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <meta name="msapplication-tap-highlight" content="no">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta http-equiv="pragma" content="no-cache" />
</head>
<body>
<!-- 图片瀑布流: start -->
<div id="imgList">
    <div class="pin"><a class="box" href="test2.html"><img src="images/dd.png" data-src="images/_1.jpg"><p>aaaaa</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="http://h.hiphotos.baidu.com/zhidao/pic/item/6a63f6246b600c3320b14bb3184c510fd8f9a185.jpg"><p>风景图1</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="http://d.hiphotos.baidu.com/zhidao/pic/item/32fa828ba61ea8d34e62be55970a304e251f581b.jpg"><p>风景图222</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>cccccccccc</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>dddddddddddd</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_4.jpg"><p>eeeeeeeeeeee</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="http://f4.topit.me/4/53/7e/11949842569497e534o.jpg"><p>ffffffff</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_1.jpg"><p>gggggg</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>hhhhhhhhh</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>iiiiiiiii</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_4.jpg"><p>jjjjjjjjj</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_5.jpg"><p>kkkkkkkkkk</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_1.jpg"><p>lllll</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>mmmmmm</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>nnnnnnnnnnn</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_1.jpg"><p>ooooooooooo</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>ppppppppp</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>qqqqqqqqqq</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_1.jpg"><p>rrrrrrrrrr</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>sssssssss</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>tttttttttttt</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_1.jpg"><p>uuuuuuuuuuu</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>vvvv</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>ww</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_1.jpg"><p>xxx</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_2.jpg"><p>yyyyyyyy</p></a></div>
    <div class="pin"><a class="box"><img src="images/dd.png" data-src="images/_3.jpg"><p>zzzz</p></a></div>
</div>
<!-- 图片瀑布流: end -->

<style type="text/css">
html,body,p{margin:0;padding:0;}
body{background:#e8e8e8;}

#imgList{position:relative;width:100%;overflow:auto;}
#imgList > .hide{display:none;}/*初始化时 .pin 会被js设为隐藏*/
#imgList > .l{float:left;padding:10px 5px 0 10px;}/*左列*/
#imgList > .r{float:right;padding:10px 10px 0 5px;}/*右列*/

#imgList .pin{position:relative;width:50%;padding:10px 5px 0 10px;box-sizing: border-box;margin:0;}
#imgList .box{display:block;background:#fff;padding:0;box-sizing:border-box;}
#imgList .box > img{width:100%;height:auto;}
#imgList .box > p{padding:14px 6px 14px 6px;font-size:14px;text-align:left;color:#333;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}
</style>
<script src="http://cdn.bootcss.com/zepto/1.1.6/zepto.min.js"></script>
<script type="text/javascript" src="waterfall.js"></script><!-- 瀑布流js -->
</body>
</html>

waterfall.js

$(function(){
/***
【两列图片瀑布流(图片高度未知)】
firstCounter:5,//设置:第一次加载几张
limit:3,//设置每次加载几张
cur:0,//当前第几张
init()方法:初始化,将所有容器设为隐藏+左浮动
loadimg()方法:给每个图片加onload事件,图片载入后,触发
waterfall()方法: 对瀑布流排序和定位(容器中如果图片未载入完毕的,依旧隐藏。)
checkscroll()方法: 滚动检测
    logTime变量:    两次滚动加载请求之间时间需大于500毫秒,避免高频率请求
scroll()方法: 发生滚动后,调用次方法
*/
var WATERFALL = {
    oParent: "",// 父级对象名
    aPin: "",// 存储块框pin的类名
    logTime:0,//最后一次滚屏操作
    Timer:null,//图片载入后,加延迟定时器

    firstCounter:8,//设置:第一次加载几张
    limit:3,//设置每次加载几张
    cur:0,//当前第几张
    init:function(parent,pin) {//初始化
        this.oParent = parent;    //parend 父级id
        this.aPin = pin;        //pin 容器
        $(this.aPin).addClass("hide").addClass("l");//初始化:先将所有容器设为隐藏+左浮动。
        this.loadimg(0,this.firstCounter);//第一次载入的图片
    },
    loadimg:function(_start,_end) {
        if(_end > $(this.aPin).length){_end = $(this.aPin).length;}//去掉超出总数的不合理数据
        this.cur = _end;
        for(var i=_start;i<_end;i++){
            var _aPin = $(this.aPin).eq(i);
            var _img = _aPin.find("img");
            _img.attr("src",_img.attr("data-src"));

            //图片load事件
            _img.bind("load",function(){
                var _aPin = $(this).parents( WATERFALL.aPin );//容器
                _aPin.removeClass("hide");//图片已载入后,显示容器
                console.log("-----图片载入次序---"+_aPin.index());

                //定时器(100毫秒后如无新图载入,计算位置;有新图载入,刷新定时器)——避免频繁重复操纵页面
                clearTimeout(WATERFALL.Timer);
                WATERFALL.Timer = setTimeout(function(){
                    WATERFALL.waterfall();
                }, 100);//100毫秒

            });
        }
    },

    waterfall:function() {
            console.log("waterfall (图片排序)----!!");
            //左右列的当前累计总高度(不包含当前容器高)
            var _sumH1=0;
            var _sumH2=0;
            $(this.aPin).eq(0).addClass("l");

            for(var i=0;i<$(this.aPin).length;i++){//遍历数组aPin的每个块框元素
                var _aPin = $(this.aPin).eq(i);
                if(_aPin.hasClass("hide")==false){//判断是否该容器的图片已载入
                    var _sumH = _aPin.position().top + _aPin.height();//当前容器相对于父元素的偏移 + 当前元素高(为下一次循环准备数据)
                    //_aPin.attr("data-sum1",_sumH1);
                    //_aPin.attr("data-sum2",_sumH2);
                    //_aPin.attr("data-h",_aPin.height());
                    if(i==0){
                        _sumH1 = _sumH;
                    }else{
                        if(_sumH2>_sumH1){
                            _aPin.removeClass("r").addClass("l");//左列
                            _sumH1  = _sumH;
                        }else{
                            _aPin.removeClass("l").addClass("r");//右列
                            _sumH2  = _sumH;
                        }
                    }
                }
            }
    },

    checkscroll:function() {
        //两次滚动请求之间时间需大于500毫秒,避免多次请求
        var curTime=new Date().getTime();
        if(this.logTime > (curTime-500) ){
            return false;
        }else{
            var oParent = $(this.oParent);
            var aPin = $(this.aPin);
            if(aPin.length==0){return false;}//空数据不作处理
            var aPinLast = aPin.eq(this.cur-1);//最后一个显示的容器
            var lastPinH =  aPinLast.offset().top + aPinLast.height()-10;//到最后一个容器的高度时,载入下一次
            var scrollTop = $(document.body).scrollTop();//滚动高度
            var windowH = $(window).height();//页面高度

            //console.log("lastPinH=" + lastPinH +",   scrollTop="+scrollTop +"--- windowH:"+windowH+"  >>> "+ (lastPinH - scrollTop -windowH ) );
            if( (lastPinH - scrollTop -windowH ) < 0 ){//到达指定高度后 返回true,触发waterfall()函数
                this.logTime = curTime;//更新时间标记
                
                //console.log("第"+this.cur+"个, 总共"+aPin.length+"个");
                if(this.cur >= aPin.length){
                    return false;
                }else{
                    this.counter++;
                    return true;
                }
            }else{
                return false;
            }
        }
    },
    scroll:function(parent,pin) {//发生滚动事件后,调用此方法
        if(this.checkscroll()){
            this.loadimg(this.cur,this.cur+this.limit);//每次需要新载入的图片
        }
    },
};

//------------------------正文--------------------------
    //1.初始化
    WATERFALL.init('#imgList','.pin');

    //2.滚屏加载
    $(window).scroll(function() {
        WATERFALL.scroll('#imgList','.pin');
    });
});

 

 

....

posted on 2015-10-14 22:25  bjhhh  阅读(3333)  评论(0编辑  收藏  举报