前面文章《vuejs实现瀑布流布局(一)》和《vuejs实现瀑布流布局(二)》已经介绍了瀑布流的基本实现的一种方法,虽然是在vuejs中实现的,可是实际上也可以把这段代码扒出来,在我们的任何项目中使用,并不局限于vuejs。

我也在项目中用这段代码实现了这种瀑布流。

后来发现一个问题,就是瀑布流布局会在每次刷新之后,排序发生变化,如果讲究一点的话,其实并没有什么特别大的影响,可是如果追求精益求精的话,确实不太理想。

看一下,瀑布流实现的关键性代码:

$("#items").children("li").each(function (index, val) {
    var $this = $(this);
    var $img = $this.find("img").first();
    $img.on("error", function () {
        $img.attr("src", "../src/assets/images/default.png");
    });

    if ($img.get(0).complete) {
        addItems();
    } else {
        $img.on("load", function () {
            addItems();
        });
    }

    function addItems() {
        if(_this.leftHeight <= _this.rightHeight){
            $l.append($this);
            _this.leftHeight = $l.height();
        }else{
            $r.append($this);
            _this.rightHeight = $r.height();
        }
    }    
    $.refreshScroller();
});

  其中的addItems就是布局瀑布流的,但是当前存在的问题就是:当从后台取回数据之后,在id="items"的ul中渲染每一项列表时,一旦图片加载完成,就立马将其布局到页面中,这就必然导致每次刷新之后页面布局排序的顺序有所不同,因为我们没有办法预计哪条数据中的图片加载先完成。

如此,如果需要修复这个问题的话,似乎只有一个可提供的方案,等待所有图片在<ul id="items"></ul>中加载完成,然后在按顺序布局到页面中。

定义一个全局变量:

imgs: {
    imgLoad: [],
    loadNums: 0
}

  在数据请求回来之后,把新请求回来的数据赋值给imgs.imgLoad,以保证imgs.imgLoad里面所存储的数据都是刚刚请求回来的数据,然后在<ul id="items"></ul>渲染之前,将imgs.loadNums = 0;重新赋值为0,然后<ul id="items"></ul>的列表li每次渲染加载img成功之后imgs.loadNums++,当imgs.loadNums值等于imgs.imgLoad的数组长度的时候,再开始页面布局。

$("#items").children("li").each(function (index, item) {
            var $this = $(item);
            var _img = $(item).find("img").first();
            _img.on("error", function () {
              _img.attr("src", "../src/assets/images/default.png");
            });
            
            _this.leftHeight = $l.height();
            _this.rightHeight = $r.height();
            if(_img.get(0).complete){
              _this.imgs.loadNums++
            } else {
              _img.on("load", function () {
                _this.imgs.loadNums++
                waterfallLayer();
              })
            }
          })

          waterfallLayer()
          function waterfallLayer() {
            if (_this.imgs.loadNums == _this.imgs.imgLoad.length) {
              $("#items").children("li").each(function (index, item) {
                if(_this.leftHeight <= _this.rightHeight){
                  $l.append($(item));
                  _this.leftHeight = $l.height();
                }else{
                  $r.append($(item));
                  _this.rightHeight = $r.height();
                }
              })
            }
          }

  就此保证了,不管怎么刷新页面,数据排序都是一致的。

 

posted on 2017-09-05 09:44  烛火星光  阅读(138)  评论(0编辑  收藏  举报