问答详情
源自:2-5 onscroll事件实现瀑布流布局的图片加载功能

算法可否优化。

感觉布局时的算法有问题,一拖动滚动所有图片就要重新排列一遍,貌似可以将最下面一排的整体高度全部记录下来,后面加载的时候就不用再全部去遍历布局了。老师讲得不错。

提问者:乘风破浪xrg 2016-02-03 14:53

个回答

  • 昨天de梦
    2016-02-05 15:58:19

    是的,我们可以修改一下 waterfall 这个函数,把参数传入,而这个参数为  新加入的“盒子”,当hArr中有“数”时,我们应该按照 先求 hArr 最小值的方式设置 “盒子”的位置,并修改hArr中的值。当hArr没有“数”,说明我们是第一次摆放盒子,那么我们向 waterfall传入的盒子就是第1批盒子,需要先正确 摆放第1行盒子,即记录 hArr 的值。

    (把hArr设置为全局变量)

    类似这样:

    //将所有 newBoxs 新盒子“放好”
    function waterfall(newBoxs) {
       var w = newBoxs[0].outerWidth(); //盒子的宽度
       //计算列数
       var cols = Math.floor(ww/w);


       $.each(newBoxs, function(index) {
           var box = newBoxs[index];
           var h = box.outerHeight();

           if(index < cols && hArr.length < cols) {  //hArr.length < cols 条件是为了区分后续的数据加载,表明已经有一行排在第1行了。
               hArr[index] = h;

               //移动第1行盒子到正确的位置
               moveBox(box, index * w, 0);
           } else {
               var minH = Math.min.apply(null, hArr);
               var minHIndex = $.inArray(minH, hArr);

               hArr[minHIndex] += box.outerHeight();
               moveBox(box, minHIndex * w, minH);
           }
       });
    }


    那么加载数据时就可以:

    $(window).on("scroll", function() {

       var boxArr = [];
       if(checkScrollSlide()) {

           $.each(dataInt.data, function(key, value) {
               $box = $("<div>").addClass("box");
               $pic = $("<div>").addClass("pic").appendTo($box);
               $img = $("<img>").attr("src", "images/" + value.src).appendTo($pic);

               boxArr.push($box);

               $box.appendTo($("#main"));
           });

            //initBoxsPos(boxArr);
           waterfall(boxArr);
       }
    });

    主要考虑的是是否是第1批数据。第2批以上的数据都是依据“最小高度”去摆放。第1批数据的第1行特例。