美文网首页
瀑布流的3种实现方式

瀑布流的3种实现方式

作者: 代艳霞 | 来源:发表于2021-09-14 13:19 被阅读0次

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

  • 瀑布流容器
<!--瀑布流容器-->
<div id="box"></div>

js代码

//接口获取数据,循环展示
 function forList(list){
             var HTML = "";
         for(var i=0;i<list.length;i++){
            HTML+='<li class="item" data="'+i+'">' ;
            HTML+='<div class="box-item">' ;
            HTML+='<img src="'+list[i].sIMG+'" alt=""><div class="text">'+list[i].sTitle+'</div>';
            HTML+= '</div>';
            HTML+= '</li>';
        }
         
             /**
              * HTML ;拼接后的字符串
              * #box,存放瀑布流的容器
              */
              // 调用瀑布流函数
             warterfall(HTML,'#box')
    }
    //拉取数据
    forList(lists1);
    // 瀑布流函数
    function warterfall(HTML,content) {
       //生成左右两个容器及暂时存放元素的容器(hidebox)
        if($(content+' ul').length<=0){
            $(content).append('<ul class="left"></ul><ul class="right"></ul><ul id="hidebox" style="display: none;"></ul>');
        }
        //数据先放在一个隐藏的容器,
        $("#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,因为这样会影响定位)代码如下:

  • 瀑布流容器
<!--瀑布流容器-->
 <ul id="content" class="force-column  listcom"></ul>

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<list.length;i++){
            HTML+='<li class="item" data="'+i+'">' ;
            HTML+='<div class="box-item">' ;
            HTML+='<img src="'+list[i].sIMG+'" alt=""><div class="text">'+list[i].sTitle+'</div>';
            HTML+= '</div>';
            HTML+= '</li>';
        }
        $("#content").append(HTML);
        setTimeout(function(){
            warterfall("content", "item");
        },3000)
    }
    forList(lists1);
    $(".btn").on('click',function () {
        forList(lists1)
    })

效果如下:


position

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

3: css实现

页面布局:

<div class="box">
<!--瀑布流存放的位置-->
    <ul id="content" class="force-column  listcom"></ul>
    <div class="btn">加载更多</div>
</div>

样式设置

 .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;
        }

假如数据是接口返回的

<script>
    var lists1 = [
                {
                    "title":"1111",
                    "img":"//sy-1254960240.cos.ap-guangzhou.myqcloud.com/smoba/ingame/images/202007/df7cd494edf5292ca388881fdd4cde852.jpg",
                },
                {
                    "title":"2222",
                    "img":"//shp.qpic.cn/cfwebcap/0/eb2832fbac46ba7182052e7e332230ba/0/?width=330&height=186",
                },
                {
                    "title":"3333",
                    "img":"//sy-1254960240.cos.ap-guangzhou.myqcloud.com/smoba/ingame/images/202007/df7cd494edf5292ca388881fdd4cde852.jpg",
                },
                {
                    "title":"4444",
                    "img":"//shp.qpic.cn/cfwebcap/0/615b9a61170c3213965092ea7cc004a6/0/?width=330&height=186",
                },
                {
                    "title":"5555",
                    "img":"//sy-1254960240.cos.ap-guangzhou.myqcloud.com/smoba/ingame/images/202007/df7cd494edf5292ca388881fdd4cde852.jpg",
                },
                {
                    "title":"6666",
                    "img":"//shp.qpic.cn/cfwebcap/0/448097ae928f6f4015758aced9e72cc7/0/?width=330&height=186",
                },
                {
                    "title":"7777",
                    "img":"//shp.qpic.cn/cfwebcap/0/f463c748a8810add5538a76b51aa6f1a/0/?width=330&height=186",
                },
                {
                    "title":"8888",
                    "img":"//shp.qpic.cn/cfwebcap/0/66585db88507b07fff35e2affa365b37/0/?width=943&height=398",
                },
                {
                    "title":"9999",
                    "img":"//sy-1254960240.cos.ap-guangzhou.myqcloud.com/smoba/ingame/images/202007/df7cd494edf5292ca388881fdd4cde852.jpg",
                 },
            ]
    function forList(list){
        var HTML = "";
        for(var i=0;i<list.length;i++){
            HTML+='<li class="item" data="'+i+'">' ;
            HTML+='<div class="box-item">' ;
            HTML+='<img src="'+list[i].img+'" alt=""><div class="text">'+list[i].title+'</div>';
            HTML+= '</div>';
            HTML+= '</li>';
        }
        $("#content").append(HTML)
            // setTimeout(function(){
            //     warterfall("content", "item");
            // },3000)
    }
    forList(lists1)
    $(".btn").on('click',function () {
        forList(lists1)
    })
</script>
  • 打开页面写,效果如下:


    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种实现方式

      本文链接:https://www.haomeiwen.com/subject/oqoaektx.html