在 Internet Explorer 中使用 IntersectionObserver polyfill 延迟加载 img 失败
Lazy loading img's with IntersectionObserver polyfill fails in Internet Explorer
我正在尝试使用可用的 IntersectionObserver 实现图像延迟加载,否则使用 polyfill(推荐 here)。
+function ($, window, document, undefined) {
var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
var lazyLoadImage = function() {
var lazyImageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var lazyImage = entry.target;
lazyImage.src = lazyImage.dataset.src;
lazyImage.classList.remove("lazy");
lazyImageObserver.unobserve(lazyImage);
}
});
});
lazyImages.forEach(function(lazyImage) {
lazyImageObserver.observe(lazyImage);
});
};
var lazyLoadImagePolyfill = function() {
var active = false;
if (active === false) {
active = true;
setTimeout(function() {
lazyImages.forEach(function(lazyImage) {
if ((lazyImage.getBoundingClientRect().top <= window.innerHeight
&& lazyImage.getBoundingClientRect().bottom >= 0)
&& getComputedStyle(lazyImage).display !== 'none') {
console.log('lazyImage:', lazyImage);
lazyImage.src = lazyImage.dataset.src;
lazyImage.classList.remove('lazy');
lazyImages = lazyImages.filter(function(image) {
return image !== lazyImage;
});
if (lazyImages.length === 0) {
document.removeEventListener('scroll', lazyLoadImagePolyfill);
window.removeEventListener('resize', lazyLoadImagePolyfill);
window.removeEventListener('orientationchange',
lazyLoadImagePolyfill);
}
}
});
active = false;
}, 200);
}
document.addEventListener("scroll", lazyLoadImagePolyfill);
window.addEventListener("resize", lazyLoadImagePolyfill);
window.addEventListener("orientationchange", lazyLoadImagePolyfill);
};
document.addEventListener('DOMContentLoaded', function(){
if ("IntersectionObserver" in window) {
lazyLoadImage();
} else {
lazyLoadImagePolyfill();
}
});
}(jQuery, window, document)
此方法在我测试过的所有浏览器中均能正常工作,IE 除外。我在控制台中得到一个 SCRIPT5007: Unable to get property 'src' of undefined or null reference
;抛出错误的行是 lazyImage.src = lazyImage.dataset.src;
。但是,该行前面的 console.log 显示以下内容:
lazyImage: [object HTMLImageElement]
"lazyImage:"
<img class="lazy" src="placeholder.png" data-src="real-pic.jpg"></img>
请注意:我被要求不要使用外部库或插件。知道为什么会发生这种情况以及如何纠正它吗?
每当我不能使用观察者时,我通常使用 in-view 来处理这类事情,但你说你被要求不要使用任何外部库或插件,所以我给你写了这段代码在香草 javascript。
此代码将 运行 在 IE9=< 上没有 polyfills。
注意:请注意,我没有对性能进行任何优化,例如,如果所有图像都已加载,请删除事件监听器等。
document.addEventListener('DOMContentLoaded', lazyLoadImagePolyfill);
function lazyLoadImagePolyfill() {
var lazyLoadImages = Array.from(document.getElementsByClassName('lazy'));
_loadImage();
window.onscroll = _loadImage;
function _loadImage() {
for (let i = 0; i < lazyLoadImages.length; i += 1) {
var img = lazyLoadImages[i];
if (isVisible(img)) {
showImage(img);
}
}
}
}
function isVisible(element) {
var {
top,
bottom
} = element.getBoundingClientRect();
var vHeight = (window.innerHeight || document.documentElement.clientHeight);
return ((top > 0 || bottom > 0) && top < vHeight);
}
function showImage(img) {
var src = img.getAttribute('data-src');
if (!src) {
return;
}
img.setAttribute('src', src);
img.onload = function() {
img.removeAttribute('data-src');
};
}
img {
margin-bottom: 200px;
min-height: 1px;
width: 100%;
display: block;
}
.container {
display: flex;
flex-wrap: wrap;
width: 400px;
margin: auto;
}
<div class="container">
<img class="lazy" data-src="http://www.facetheforce.today/han-old/400" alt="Han Solo Old">
<img class="lazy" data-src="http://www.facetheforce.today/han/400" alt="Han Solo">
<img class="lazy" data-src="http://www.facetheforce.today/luke-old/400" alt="Luke Old">
<img class="lazy" data-src="http://www.facetheforce.today/luke/400" alt="Luke">
<img class="lazy" data-src="http://www.facetheforce.today/han-old/400">
</div>
我正在尝试使用可用的 IntersectionObserver 实现图像延迟加载,否则使用 polyfill(推荐 here)。
+function ($, window, document, undefined) {
var lazyImages = [].slice.call(document.querySelectorAll("img.lazy"));
var lazyLoadImage = function() {
var lazyImageObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
var lazyImage = entry.target;
lazyImage.src = lazyImage.dataset.src;
lazyImage.classList.remove("lazy");
lazyImageObserver.unobserve(lazyImage);
}
});
});
lazyImages.forEach(function(lazyImage) {
lazyImageObserver.observe(lazyImage);
});
};
var lazyLoadImagePolyfill = function() {
var active = false;
if (active === false) {
active = true;
setTimeout(function() {
lazyImages.forEach(function(lazyImage) {
if ((lazyImage.getBoundingClientRect().top <= window.innerHeight
&& lazyImage.getBoundingClientRect().bottom >= 0)
&& getComputedStyle(lazyImage).display !== 'none') {
console.log('lazyImage:', lazyImage);
lazyImage.src = lazyImage.dataset.src;
lazyImage.classList.remove('lazy');
lazyImages = lazyImages.filter(function(image) {
return image !== lazyImage;
});
if (lazyImages.length === 0) {
document.removeEventListener('scroll', lazyLoadImagePolyfill);
window.removeEventListener('resize', lazyLoadImagePolyfill);
window.removeEventListener('orientationchange',
lazyLoadImagePolyfill);
}
}
});
active = false;
}, 200);
}
document.addEventListener("scroll", lazyLoadImagePolyfill);
window.addEventListener("resize", lazyLoadImagePolyfill);
window.addEventListener("orientationchange", lazyLoadImagePolyfill);
};
document.addEventListener('DOMContentLoaded', function(){
if ("IntersectionObserver" in window) {
lazyLoadImage();
} else {
lazyLoadImagePolyfill();
}
});
}(jQuery, window, document)
此方法在我测试过的所有浏览器中均能正常工作,IE 除外。我在控制台中得到一个 SCRIPT5007: Unable to get property 'src' of undefined or null reference
;抛出错误的行是 lazyImage.src = lazyImage.dataset.src;
。但是,该行前面的 console.log 显示以下内容:
lazyImage: [object HTMLImageElement]
"lazyImage:"
<img class="lazy" src="placeholder.png" data-src="real-pic.jpg"></img>
请注意:我被要求不要使用外部库或插件。知道为什么会发生这种情况以及如何纠正它吗?
每当我不能使用观察者时,我通常使用 in-view 来处理这类事情,但你说你被要求不要使用任何外部库或插件,所以我给你写了这段代码在香草 javascript。 此代码将 运行 在 IE9=< 上没有 polyfills。
注意:请注意,我没有对性能进行任何优化,例如,如果所有图像都已加载,请删除事件监听器等。
document.addEventListener('DOMContentLoaded', lazyLoadImagePolyfill);
function lazyLoadImagePolyfill() {
var lazyLoadImages = Array.from(document.getElementsByClassName('lazy'));
_loadImage();
window.onscroll = _loadImage;
function _loadImage() {
for (let i = 0; i < lazyLoadImages.length; i += 1) {
var img = lazyLoadImages[i];
if (isVisible(img)) {
showImage(img);
}
}
}
}
function isVisible(element) {
var {
top,
bottom
} = element.getBoundingClientRect();
var vHeight = (window.innerHeight || document.documentElement.clientHeight);
return ((top > 0 || bottom > 0) && top < vHeight);
}
function showImage(img) {
var src = img.getAttribute('data-src');
if (!src) {
return;
}
img.setAttribute('src', src);
img.onload = function() {
img.removeAttribute('data-src');
};
}
img {
margin-bottom: 200px;
min-height: 1px;
width: 100%;
display: block;
}
.container {
display: flex;
flex-wrap: wrap;
width: 400px;
margin: auto;
}
<div class="container">
<img class="lazy" data-src="http://www.facetheforce.today/han-old/400" alt="Han Solo Old">
<img class="lazy" data-src="http://www.facetheforce.today/han/400" alt="Han Solo">
<img class="lazy" data-src="http://www.facetheforce.today/luke-old/400" alt="Luke Old">
<img class="lazy" data-src="http://www.facetheforce.today/luke/400" alt="Luke">
<img class="lazy" data-src="http://www.facetheforce.today/han-old/400">
</div>