<script>
if ('loading' in HTMLImageElement.prototype) {
const images = document.querySelectorAll('img[loading="lazy"]');
images.forEach((img) => {
img.src = img.dataset.src;
});
} else {
// polyfill
// use IntersectionObserver if support it
// else use `getBoundingClientRect`
}
</script>
<iframe loading=lazy> 已被标准化,并已在 Chromium 中实施。
基于 IntersectionObserver
document.addEventListener('DOMContentLoaded', () => {
const lazyImages = [].slice.call(document.querySelectorAll('img.lazy'));
if ('IntersectionObserver' in window) {
const options = {
root: document,
rootMargin: '0px',
threshold: 1.0
};
const lazyImageObserver = new IntersectionObserver((
entries,
observer,
) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const lazyImage = entry.target;
lazyImage.src = lazyImage.dataset.src;
lazyImage.srcset = lazyImage.dataset.srcset;
lazyImage.classList.remove('lazy'); // for lazy load css img
lazyImageObserver.unobserve(lazyImage);
}
});
}, options);
lazyImages.forEach(lazyImage) => {
lazyImageObserver.observe(lazyImage);
});
} else {
// Possibly fall back to event handlers here
}
});
浏览器会在请求外部资源之前检查 CSS 是否应用于 Document。 对于 CSS 中的图片可以通过不同的 class 进行图片懒加载。
<div class="background lazy-background">
<h1>Here's a hero heading to get your attention!</h1>
<p>Here's hero copy to convince you to buy a thing!</p>
<a href="/buy-a-thing">Buy a thing!</a>
</div>
.background {
background-image: url('hero.jpg'); /* The final image */
}
.lazy-background {
background-image: url('hero-placeholder.jpg') !import; /* Placeholder image */
}
if (inView(element)) {
element.classList.remove('lazy-background');
}