瀑布流的3种实现方式

1:js 两列布局实现,思路:左右分为两个容器,根据容器的高度(相对低的那一个)决定下一个元素应该放在哪个容器内,这样视觉就实现了瀑布流的效果,代码如下:

  • 瀑布流容器

js代码

//接口获取数据,循环展示
 function forList(list){
             var HTML = "";
         for(var i=0;i' ;
            HTML+='
' ; HTML+='
'+list[i].sTitle+'
'; HTML+= '
'; HTML+= ''; } /** * HTML ;拼接后的字符串 * #box,存放瀑布流的容器 */ // 调用瀑布流函数 warterfall(HTML,'#box') } //拉取数据 forList(lists1); // 瀑布流函数 function warterfall(HTML,content) { //生成左右两个容器及暂时存放元素的容器(hidebox) if($(content+' ul').length<=0){ $(content).append('
      '); } //数据先放在一个隐藏的容器, $("#hidebox").html(HTML); //取出元素 var items=$("#hidebox li"); //获取左右两个容器 var leftbox=$(content+' .left'); var rightbox=$(content+' .right'); //设置延迟,保证图片加载完成,避免影响左右容器高度的计算,导致数据放到错误的位置 setTimeout(function () { // 左边容器高度 var leftDivHeight = leftbox.height(); // 右边容器高度 var rightDivHeight =rightbox.height(); items.each(function (index,item) { //瀑布流函数,该函数计算左右容器的总高度,决定把下一个元素放在哪个容器里面 //获取左右容器高度 leftDivHeight = leftbox.height(); rightDivHeight = rightbox.height(); //把下一个元素放在高度低的容器里面 if(leftDivHeight<=rightDivHeight) { leftbox.append(item); return; } rightbox.append(item); }) },500) };

      效果如下:


      优化瀑布流

      2:js position定位,思路:js记录左右两列的所有元素并计算总高度,决定下一个元素的放置位置(注意:元素与元素之间不能用margin,因为这样会影响定位)代码如下:

      • 瀑布流容器
      
       

        js代码

         function warterfall(parent, box) {
                 //瀑布流函数,该函数将图片定位到上一行高度最小图片下方,接数据,更新dom后,重新执行该函数
                //将main下的所有class为box的元素取出来
                var oParent = $('#'+parent);
                var oBoxs =oParent.find('.'+box);
                //计算整个页面显示的列数(页面宽/box的宽);
                var oBoxW = oBoxs.eq(0).width();
                var cols = 2;
                var hArr = [];
                for (var i = 0; i < oBoxs.length; i++) {
                    var currentBox=oBoxs.eq(i);
                    if (i < cols) {
                        // 将前2张图片的宽度记录到hArr数组中(第一行的高度)
                        hArr.push(currentBox.height());
                    } else {
                        //从第二行开始就开始找最小的高度了,决定待插入图片该插入到哪里
                        // 找到高度最小的值
                        var minH = hArr[0]>hArr[1]?hArr[1]:hArr[0];
                        var index = hArr.indexOf(minH);
                        // 设置最小高度的图片的style为绝对定位,并设置top和left
                        currentBox.css({
                            'position':'absolute',
                            'top': minH ,
                            'left': oBoxW * index
                        });
                        //高度叠加
                        hArr[index] += currentBox.height();
                    }
                }
            };
          function forList(list){
                var HTML = "";
                for(var i=0;i' ;
                    HTML+='
        ' ; HTML+='
        '+list[i].sTitle+'
        '; HTML+= '
        '; HTML+= ''; } $("#content").append(HTML); setTimeout(function(){ warterfall("content", "item"); },3000) } forList(lists1); $(".btn").on('click',function () { forList(lists1) })

        效果如下:


        position

        完美实现,但是它每次都需要获取全部元素,再重新定位,很耗性能。

        3: css实现

        页面布局:

          加载更多

          样式设置

           .box{
                      width: 100%;
                      height: 600px;
                      overflow: scroll;
                  }
                  .box .force-column {
                      width: 100%;
                      position: relative;
                      overflow-x: hidden;
                        /*设置元素分几列显示*/
                      -moz-column-count: 2;
                      -webkit-column-count: 2;
                      column-count: 2;
                  }
                  .box-item{
                      width: 200px;
                      background: yellowgreen;
                  }
                  img{
                      width: 200px;
                      height: auto;
                  }
          

          假如数据是接口返回的

          
          
          • 打开页面写,效果如下:


            css实现

          效果虽然实现了,但是美中不足的是,他有个问题:数据不是按照1-2-3-4,的顺序来排列的,而是左边是1,3,5,右边是2,4,6。对于需要展示的数据对排序有要求的话(比如排行榜),此种方法不合适;如何来解决这个bug,很简单,就是我们需要对数据进行二次处理,把1,3,5数据放在前面,2,4,6f放在后面,这样就可以了,代码如下:

             //数据处理1,3,5,放前面,2,4,6放后面
              function dataFilter(lists){
                  var leftArr=[];
                  var rightArr=[];
                  $.each(lists,function (index,value) {
                     if(index%2==0) {
                         leftArr.push(value)
                     }else {
                         rightArr.push(value)
                     }
                  })
                  var currentArr= [].concat(leftArr,rightArr);
                  return currentArr
              }
                forList(dataFilter(lists))
          

          效果如下:


          简单数据处理
          • ,此时数据看起来是按照顺序排列的,并且均分放置,也就是两列的列表个数几乎是一样的,但是如果两边的数据因为文字或者图片差异比较大,是否会导致两列高度差异比较大的问题呢?,我们来修改数据看一下,比如增加一些文字,效果如下:


            增加文字

          此时看到的结果是:即使两列数据不同,不会导致两列的高度差异很大,因为根据高度差,数据的排列已经发生了改变,比如,第7个列表笨应该放在第一列的最后,现在因为两边高度的问题,而自动放在了第2列的第一位,也就是我们之前的担心是多余的,系统已经做了处理,但是这样的实现方式,还是有我们之前顾虑的问题,就是对数据的排列有要求的需求,这种方法是不适合的。

          以上就是我想到的瀑布流的几种实现方式,欢迎大家有更好的方式的话,我们一起交流一下

          你可能感兴趣的:(瀑布流的3种实现方式)