我正在创建延迟加载函数,并且在成功加载图像以创建平滑过渡之后,我想将图像附加到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。
答案 0 :(得分:1)
您添加的onload回调实际上已被正确触发。
在这种特殊情况下,问题在于使用var
声明的变量是函数范围的。这意味着for
循环完成迭代后,对于lazyLoadElement
处理程序触发的所有处理程序,onload
变量都指向同一元素。
将lazyloadElement
,imgData
,image
和lazyStyle
的声明从var
更改为let
将使代码按预期工作。