在瀑布流中实现懒加载,刚加载时图片叠在一起的问题(原生JS)

https://segmentfault.com/a/11...
参考了这篇文章的懒加载

问题描述:图片刚出来时全叠在一起(把lazyLoad写在onload里只是便于测试),改变窗口的大小时图片恢复正常,请问这个问题怎么解决?

image

改变窗口大小后:
image

贴代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>瀑布流</title>
    <link rel="stylesheet" href="./css/index.css">
    <link rel="stylesheet" href="./css/reset.css">
    <script src="./js/index.js"></script>
</head>
<body>
    <div class="wrapper">
        ![](./imgs/1.jpg)
        ![](./imgs/2.jpg)
        ![](./imgs/3.jpg)
        ![](./imgs/4.jpg)
        ![](./imgs/5.jpg)
        ![](./imgs/6.jpg)
        ![](./imgs/7.jpg)
        ![](./imgs/8.jpg)
        ![](./imgs/9.jpg)
        ![](./imgs/10.jpg)
        ![](./imgs/11.jpg)
        ![](./imgs/12.jpg)
        ![](./imgs/13.jpg)
        ![](./imgs/14.jpg)
        ![](./imgs/15.jpg)
        ![](./imgs/16.jpg)
        ![](./imgs/17.jpg)
        ![](./imgs/18.jpg)
        ![](./imgs/19.jpg)
        ![](./imgs/20.jpg)
        ![](./imgs/21.jpg)
        ![](./imgs/22.jpg)
        ![](./imgs/23.jpg)
        ![](./imgs/24.jpg)
        ![](./imgs/25.jpg)
        ![](./imgs/27.jpg)
        ![](./imgs/28.jpg)
        ![](./imgs/29.jpg)
        ![](./imgs/30.jpg)
        ![](./imgs/31.jpg)
        ![](./imgs/32.jpg)
        ![](./imgs/33.jpg)
        ![](./imgs/34.jpg)
        ![](./imgs/35.jpg)
        ![](./imgs/36.jpg)
        ![](./imgs/37.jpg)
        ![](./imgs/38.jpg)
        ![](./imgs/39.jpg)
        ![](./imgs/40.jpg)
        ![](./imgs/41.jpg)
        ![](./imgs/42.jpg)
        ![](./imgs/43.jpg)
        ![](./imgs/44.jpg)
        ![](./imgs/45.jpg)
        ![](./imgs/46.jpg)
        ![](./imgs/47.jpg)
        ![](./imgs/48.jpg)
        ![](./imgs/49.jpg)
        ![](./imgs/50.jpg)
        ![](./imgs/51.jpg)
        ![](./imgs/52.jpg)
        ![](./imgs/53.jpg)
        ![](./imgs/54.jpg)
        ![](./imgs/55.jpg)
        ![](./imgs/56.jpg)
        ![](./imgs/57.jpg)
        ![](./imgs/58.jpg)
        ![](./imgs/59.jpg)
        ![](./imgs/60.jpg)
        ![](./imgs/61.jpg)
        ![](./imgs/62.jpg)
        ![](./imgs/63.jpg)
        ![](./imgs/64.jpg)
        ![](./imgs/65.jpg)
        ![](./imgs/66.jpg)
        ![](./imgs/67.jpg)
        ![](./imgs/68.jpg)
        ![](./imgs/69.jpg)
        ![](./imgs/70.jpg)
        ![](./imgs/71.jpg)
        ![](./imgs/72.jpg)
        ![](./imgs/73.jpg)
    </div>
</body>
</html>
.wrapper{
    width: 100%;
    margin: 0 auto;
    position: relative;
}
img{
    width: 291.8px;
    border-radius: 0.3em;
    box-shadow: 0 2px 4px 0 rgba(34,36,38,0.2),0 2px 10px 0 rgba(34,36,38,0.1);
    cursor: pointer;
    position: absolute;
}
let items = document.getElementsByClassName("item");
let gap = 12;

function waterFall(){
    let pageWidth = getClient().width;
    let itemWidth = items[0].offsetWidth;
    //列数 = 页面的宽度 / 图片的宽度
    let columns = parseInt(pageWidth/(itemWidth + gap));
    //定义一个数组,用来存储元素的高度
    let arr = [];
    for(let i = 0; i < items.length; i++){
        if(i < columns){
            //满足这个条件则说明在第一行
            items[i].style.top = 0;
            items[i].style.left = (itemWidth + gap) * i + 'px';
            arr.push(items[i].offsetHeight);
        }
        else{
            //其他行,先找出最小高度列,和索引
            let minHeight = arr[0];
            let index = 0;
            for(let j = 0; j < arr.length; j++){
                if(minHeight > arr[j]){
                    minHeight = arr[j];
                    index = j;
                } 
            }
            items[i].style.top = arr[index] + gap + 'px';
            items[i].style.left = items[index].offsetLeft + 'px';
            arr[index] = arr[index] + items[i].offsetHeight + gap;
        }
    }
}
//clientWidth 兼容性处理
function getClient(){
    return{
        width : window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth,
        Height : window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
    }
}
//scrollTop兼容性处理
function getScrollTop(){
    return window.pageYOffset || document.documentElement.scrollTop;
}

// num用于统计当前显示到了哪一张图片,避免每次都从第一张图片开始检查是否露出
let num = 0;

function lazyLoad(){
    let viewHeight = getClient().Height;
    for (let i = num; i < items.length; i++) {
        // 用可视区域高度减去元素顶部距离可视区域顶部的高度
        let distance = viewHeight - items[i].getBoundingClientRect().top;
        // 如果可视区域高度大于等于元素顶部距离可视区域顶部的高度,说明元素露出
        if (distance >= 0) {
          // 给元素写入真实的src,展示图片
          items[i].src = items[i].getAttribute("data-src");
          // 前i张图片已经加载完毕,下次从第i+1张开始检查是否露出
          num = i + 1;
        }
    }
}
function debounce(fn, delay = 500) {
    //防抖函数
    let timer = null;
    return function (...args) {
      if (timer) clearTimeout(timer);
      timer = setTimeout(() => {
        fn.call(this, args);
      }, delay);
    };
}
window.onload = function(){
    waterFall();
    lazyLoad();
}
window.addEventListener("scroll", debounce(lazyLoad, 600), false);

//当页面尺寸发生变化时,触发函数,实现响应式
window.onresize = function () {
    waterFall();
}

求大佬支招,感激不尽~!

阅读 1.7k
1 个回答

突然有个灵感,你可以试试

<img class="item" ... /> 加载完成后,增加 class item-loaded

/* .item 默认不显示 */
.wrapper .item {display:none;}
/* .item-loaded 默认显示 */
.wrapper .item-loaded {display:block;}
/* 任意一个未加载完成的 .item,其后的 .item-loaded 依然不显示 */
.wrapper .item:not(.item-loaded) ~ .item-loaded {display:none;}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏