在使用<picture>
的HTML5规范时,我一直在搜索(不成功)一个可靠的方法来延迟加载图像。目前大多数解决方案/插件都依赖于使用data-
属性。我可能是错的,但似乎这种方法不会与<picture>
一起使用。
我真的只是想指向正确的方向。如果有人有他们正在使用的解决方案,我很乐意看到。谢谢!
更新: 这是HTML5规范的标准标记:
<picture width="500" height="500">
<source media="(min-width: 45em)" src="large.jpg">
<source media="(min-width: 18em)" src="med.jpg">
<source src="small.jpg">
<img src="small.jpg" alt="">
</picture>
使用在Chrome和Firefox中测试的图片元素和交叉观察者来延迟加载图像的工作示例。 Safari不支持交叉观察者,因此图像立即加载,IE11不支持该元素,因此我们回退到默认的img
媒体attr中的媒体查询是任意的,可以设置为适合。
宽度阈值设置为960px - 尝试在此宽度之上和之下重新加载,以查看当图像滚动到视口时正在下载的图像的中(-m)或大(-1)变化。
<!-- Load images above the fold normally -->
<picture>
<source srcset="img/city-m.jpg" media="(max-width: 960px)">
<source srcset="img/city-l.jpg" media="(min-width: 961px)">
<img class="fade-in" src="img/city-l.jpg" alt="city"/>
</picture>
<picture>
<source srcset="img/forest-m.jpg" media="(max-width: 960px)">
<source srcset="img/forest-l.jpg" media="(min-width: 961px)">
<img class="fade-in" src="img/forest-l.jpg" alt="forest"/>
</picture>
<!-- Lazy load images below the fold -->
<picture class="lazy">
<source data-srcset="img/river-m.jpg" media="(max-width: 960px)">
<source data-srcset="img/river-l.jpg" media="(min-width: 961px)">
<img data-srcset="img/river-l.jpg" alt="river"/>
</picture>
<picture class="lazy">
<source data-srcset="img/desert-m.jpg" media="(max-width: 960px)">
<source data-srcset="img/desert-l.jpg" media="(min-width: 961px)">
<img data-srcset="img/desert-l.jpg" alt="desert"/>
</picture>
和JS:
document.addEventListener("DOMContentLoaded", function(event) {
var lazyImages =[].slice.call(
document.querySelectorAll(".lazy > source")
)
if ("IntersectionObserver" in window) {
let lazyImageObserver =
new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
let lazyImage = entry.target;
lazyImage.srcset = lazyImage.dataset.srcset;
lazyImage.nextElementSibling.srcset = lazyImage.dataset.srcset;
lazyImage.nextElementSibling.classList.add('fade-in');
lazyImage.parentElement.classList.remove("lazy");
lazyImageObserver.unobserve(lazyImage);
}
});
});
lazyImages.forEach(function(lazyImage) {
lazyImageObserver.observe(lazyImage);
});
} else {
// Not supported, load all images immediately
lazyImages.forEach(function(image){
image.nextElementSibling.src = image.nextElementSibling.dataset.srcset;
});
}
});
最后一个想法是,如果您来回更改屏幕宽度,则会再次重复下载图像文件。如果我可以将上述方法绑定到缓存检查,那么这将是金色的......