Image.onload回调触发不一致

时间:2018-07-17 09:51:40

标签: javascript css ecmascript-6 lazy-loading onload

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

我有一个函数,该函数遍历具有特定类的元素列表,每次滚动时,该列表逐渐变小。

一旦该列表中的图像被视为“可见”,我将添加一个类,并且该类不再由该函数进行评估。

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

我做了一些CSS道具操作,并在添加了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;


        }
    } 
}

以下是显示问题的小提琴: 红色元素-不可见 蓝色元素-可见,但无图像 绿色元素-在加载的图片中可见

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

请勿使用jQuery。

1 个答案:

答案 0 :(得分:1)

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

lazyloadElementimgDataimagelazyStyle的声明从var更改为let将使代码按预期工作。