Image.onload 回调触发不一致

Image.onload callback is firing inconsistently

我正在创建延迟加载功能,我想在图像成功加载后将图像附加到 DOM 以创建平滑过渡。

我有一个循环遍历具有特定 class 的元素列表的函数,每次滚动时它会逐渐变小。

一旦该列表中的图像被考虑 "visible" 我添加一个 class 并且它不再被函数评估。

我通过数据属性获取SRC,并创建一个新的Image();

我做了一些 css prop 操作,并在添加 onload 函数后添加 src。

这大约有 1/3 的时间有效,大多数图像从不触发 onload 回调并且不会添加到 DOM。

我的脚本如下:

var lazyClass = 'js-lazyload';

function lazyLoader() {

//Sets an elements var that checks how many non-visible elements still exist
// This variable is reset every time lazyLoader() is called
var elements = document.querySelectorAll('.' + lazyClass + ':not(.js-lazyload--visible)');

//If there are no hidden elements left, end the function we don't need to proceed.
if (elements.length === 0) return;

//Loop through the elements array
//Only untoggled elements can be in this array because of the previous check
 for(var i = elements.length; i--;) {

    var lazyLoadElement = elements[i];

    if (
     lazyLoadElement.getBoundingClientRect().bottom <= window.innerHeight && 
     lazyLoadElement.getBoundingClientRect().bottom > 0 || 
     lazyLoadElement.getBoundingClientRect().top <= window.innerHeight && 
     lazyLoadElement.getBoundingClientRect().top > 0) 
     {
     //The element was considered visible, let's go!
     lazyLoadElement.classList.add('js-lazyload--visible');

          var imgData = lazyLoadElement.getAttribute('data-image'),
                  image = new Image(),
                  lazyStyle = window.getComputedStyle(lazyLoadElement);

            if(lazyStyle.position !== 'relative'){
                if(lazyStyle.position !== 'absolute'){
                    lazyLoadElement.style.position = 'relative';
                }
            }

            image.onload = () => {
                lazyLoadElement.classList.add('js-lazyload--loaded');
                lazyLoadElement.insertBefore(image, lazyLoadElement.firstChild);
            }

            image.classList.add('js-lazyload__image')
            image.style.position = 'absolute';
            image.style.top = 0;
            image.style.left = 0;
            image.style.width = '100%';
            image.style.height = '100%';
            image.style.zIndex = '-1';
            image.style.objectFit = 'cover';
            image.src = imgData;


        }
    } 
}

这里有一个 fiddle 显示了这个问题: 元素红色 - 不可见 元素蓝色 - 可见,但没有图像 元素绿色 - 加载图像可见

https://jsfiddle.net/dalecarslaw/yumv6rft/

否jQuery请

您添加的 onload 回调实际上已正确触发。 这种特殊情况下的问题是使用 var 声明的变量是函数范围的。这意味着当您的 for 循环完成它的迭代时,lazyLoadElement 变量指向所有被 onload 处理程序触发的处理程序的相同元素。

lazyloadElementimgDataimagelazyStyle 的声明从 var 更改为 let 将使代码像打算。