牛刀试手之折腾瀑布流

      其实很久之前就有朋友问我有没有弄过瀑布流,当时这个东西我知道它的实现后的形式,就是蘑菇街那种啊,然后我又懒得想做,就找了一个网上的实现方式直接给了他了,我连想一下怎样实现都没有想,最后,“报应”来了,百度一面的时候,最后就问到瀑布流的实现了,然后也凸显一大弱点就是缺少必要的实战,细想一下,前端的知识,我都是通过自学的,看书占据课余比较大的时间,实战经验确实少,做重构的居多,没有试过从后台中拿数据,接着展示出整个页面,现在还停留在相对浅的状态。

      所以这次我要吸取教训,首先先折腾这个瀑布流,首先,究竟瀑布流是怎样实现的呢?百度一下,发现了挺多的相关网站,挑选了挺多看了一下,这里推荐一下一些感觉挺不错的文字,淘宝UED的瀑布流布局浅析,还有张鑫旭大神的折腾:瀑布流布局(基于多栏列表流体布局实现)。接着就是我的折腾时候了,布局就选择了传统多列浮动,为啥呢?简单嘛。

  首先,准备工作,一大堆的图片,一个json文件(仿照从后端拿回的数据)。然后,就想怎样一步一步的实现,先是要多少个参数呢,还有把那几列给生成出来,怎样添加图片呢,怎样检测到滚动条滚到最下呢。

  折腾了好一会把代码给敲出来了,由于是新手,轻拍哈。代码有点恶心。

<div class="pubu" id="pubu">
</div>
(function(){
                
        var pubu={
            container:"pubu",                //包含着整个瀑布流的容器ID
            columnWidth:239,                 //每列的宽度
            marginR:8,                       //列与列之间的间隔
            loadNum:16,                      //每次加载多少个
            datas:null,                      //从后台返回到的json数据
            colNum:5,                        //多少列
            hasLoadNum:0,                    //已经加载了多少个数据
            totalNum:1000,                   //总共有多少个,初始值很大,这里设为了1000
            createFirst:function(){          //向容器插入列,列是浮动
                var contain=document.getElementById(this.container),i,
                    colNum=this.colNum,
                    createNode=document;
                for(i=0;i<colNum;i++){
                    var div=createNode.createElement("div");
                    div.style.width=this.columnWidth+"px";
                    div.className="list a"+i;
                    if(i<colNum-1)
                    {
                        div.style.marginRight=this.marginR+"px";
                    }
                    div.style.cssFloat="left";
                    contain.appendChild(div);
                }
                return this;
            },
            callData:function(callback){                      //获取数据,这里我用了ajax同步,但是如果数据很大很大的时候,还是用异步最好
                var xmlHttp=new XMLHttpRequest(),that=this;      //但是这里我不知道应该怎么处理好了。
                xmlHttp.onreadystatechange=function(){
                    if(xmlHttp.readyState===4){
                        if(xmlHttp.status>=200&&xmlHttp.status<300||xmlHttp.status===304){
                            var data=JSON.parse(xmlHttp.responseText);         
                            callback(data);                             //使用回调函数
                        }
                    }
                }
                xmlHttp.open("get","pics.php",true);
                xmlHttp.send(null);

            },
            findShort:function(){                            //获取高度最小的那一列
                var lists=document.querySelectorAll(".list"),minHeight,k=0;
                minHeight=lists[0].offsetHeight;
                               
                for(var i=1,len=lists.length;i<len;i++){
                    var here=lists[i].offsetHeight;                                    
                    if(minHeight>here){
                        minHeight=here;
                        k=i;
                    }
                }
                return lists[k];
            },
            insertPic:function(){                    //向最短的那一列,插入图片                                
                var div=document.createElement("div"),
                    a=document.createElement("a"),
                    img=document.createElement("img");                          
                                this.totalNum=this.datas.length;                              
                img.src=this.datas[this.hasLoadNum].url;
                img.title=this.datas[this.hasLoadNum].name;
                                img.width="230";
                this.hasLoadNum++;
                a.appendChild(img);
                div.appendChild(a);
                this.findShort().appendChild(div);
            },
            insertList:function(){             //插入loadNum个图片,最后剩下少于loadNum个图片时作一点处理
               var n=this.loadNum;
               if(this.totalNum-this.hasLoadNum<n){
                    n=this.totalNum-this.hasLoadNum;
                }
                for(var i=0;i<n;i++){
                    this.insertPic();
                }                            
                return this;
            },
            insertAll:function(){
          var that=this;
this.callData(function(data){
            that.datas=data;
            that.insertList();
          }); //获取数据
//加进列里面 return this; }, throttle:function(method,context){ //一个函数节流的函数 clearTimeout(method.tId); method.tId=setTimeout(function(){ method.call(context); },100); }, addEvent:function(){ //当鼠标滚到最下面时,依次加入一定数量的图片 var pubu=this; var method=function(){   var that=document;   var buffer=that.documentElement.scrollHeight-that.documentElement.clientHeight;   if(window.scrollY===buffer)   {    pubu.insertList();    } }; document.addEventListener("scroll",function(){ pubu.throttle(method); });return this; } } pubu.createFirst().insertAll().addEvent(); })();

自评:其实这个代码还有很多不足的地方,就如那个ajax部分,一开始为了得到数据,我使用了同步方法,但是这样不符合ajax的特性,后面听了一下别人的建议,我尝试使用回调函数。

原文地址:https://www.cnblogs.com/zhuyingyan/p/2738618.html