使用 IntersectionObserver API 实现延迟加载
IntersectionObserver 的功能是什么?
示例用法
HTML 设置
CSS 设置
JS 设置
结论
各位dev.to的朋友们好!这是我的第一篇帖子——耶!非常兴奋地想和大家分享我最近学习到的关于懒加载的知识。请大家多多指教,告诉我如何才能做得更好!
图片懒加载对于加载包含大量内容的页面非常有用。我们可以轻松找到实现此功能的库,例如yall.js和lozad.js。这些库的共同之处在于它们都使用了Intersection Observer API。让我们学习如何使用它IntersectionObserver,以便了解这些库的工作原理——甚至可以编写我们自己的库!
首先,我将简要解释它的作用;IntersectionObserver其次,我将介绍如何使用它来实现自定义图片的延迟加载。
IntersectionObserver 的功能是什么?
(通俗地说)IntersectionObserver 异步检测元素何时与祖先元素(通常是视口)相交,并调用回调函数。
想象一个包含图片的视口。页面加载时,一些图片直接位于视口内,而另一些则位于视口下方,等待用户向下滚动才能看到。随着用户向下滚动,一些位置较低的图片的顶部最终会与视口底部重叠。当第一个顶部图片像素与视口重叠时,回调函数就会加载该图片。
示例用法
让我们一起阅读文档吧!Mozilla 为我们提供了一个很好的起点。
var options = {
root: document.querySelector('#scrollArea'),
rootMargin: '0px',
threshold: 1.0
}
var observer = new IntersectionObserver(callback, options);
var target = document.querySelector('#listItem');
observer.observe(target);
以上是延迟加载的最低设置#listItem(从技术上讲,选项是可选的,因此var observer = new IntersectionObserver(callback);是一种更简洁的运行方式)。
好的,我们把它应用到一个更实际的场景中。我们将:
- 我们有 10 张 HTML 图片,我们将采用延迟加载的方式加载它们。
- 添加 CSS 淡入淡出动画
- 添加 IntersectionObserver 以加载图像
HTML 设置
<div><img data-src=”http://placehold.it/300x300?text=1"></div>
<div><img data-src=”http://placehold.it/300x300?text=2"></div>
<div><img data-src=”http://placehold.it/300x300?text=3"></div>
<div><img data-src=”http://placehold.it/300x300?text=4"></div>
<div><img data-src=”http://placehold.it/300x300?text=5"></div>
<div><img data-src=”http://placehold.it/300x300?text=6"></div>
<div><img data-src=”http://placehold.it/300x300?text=7"></div>
<div><img data-src=”http://placehold.it/300x300?text=8"></div>
<div><img data-src=”http://placehold.it/300x300?text=9"></div>
<div><img data-src=”http://placehold.it/300x300?text=10"></div>
如果你仔细观察,会发现它并没有使用src`<img>`data-src属性。一种延迟加载策略是从 HTML 的 `<img>` 属性开始,data-*因为data-src这样不会加载图片。
CSS 设置
.fade {
animation-duration: 3s;
animation-name: fade;
}
@keyframes fade {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
此设置是可选的。我认为使用淡入淡出动画进行图像懒加载有助于我们的观察(而且也更美观)。
顺便说一下,如果你使用 Chrome DevTools,可以在网络选项卡中查看图像何时下载完成。
JS 设置
我希望图片只有当其50%的面积与视口重叠时才加载。以下是设置方法:
const images = document.querySelectorAll(‘img’)
const observer = new IntersectionObserver(entries => {
entries.forEach(entry => {
if(entry.isIntersecting) {
const target = entry.target
target.setAttribute(‘src’, target.dataset.src)
target.classList.add(‘fade’)
observer.unobserve(target)
}
})
}, {
threshold: 0.5
})
images.forEach(image => observer.observe(image))
我想重点谈谈我在学习 IntersectionObserver 时遇到的一些难以理解的问题。
-
参数 entries 代表了所有图像元素(我觉得用`and`
IntersectionObserver迭代两次有点奇怪,但这就是实现方式)。页面初始加载时,所有 entries 都会被调用。有些 entries 会立即相交(如果它们在页面渲染时位于视口内),而有些则不会。那些立即相交的 entries 的回调函数会立即被调用。images.forEachentries.forEach -
entry.isIntersecting当图像与视口相交时返回 true。另一种常见的相交性检查方法是entry.intersectionRatio > 0…… -
如前所述,延迟加载的常见策略是初始状态下不加载任何内容。我们在用户即将看到内容之前,才
src将值从data-src源页面传递到目标页面。src -
加载对象后取消观察是一种良好的实践。我们可以使用 `and` 或`or`选项
来更改交叉性的程度或位置。祖先元素可以通过 `root` 来更改(默认为视口)。thresholdrootMargin
结论
截至撰写本文时,intersectionObserver 可在除 IE 以外的主流浏览器中使用。请访问caniuse网站查看完整列表。
IntersectionObserver通过在回调函数中将 data-src 的值传递给 src,可以实现元素的延迟加载到视口中。同样的策略也可以应用于其他元素。
以下是我读过的一些IntersectionObserver我觉得很有用的文章(我与它们没有任何关联,只是很欣赏它们提供的信息,希望也能对您有所帮助!)
如果您发现任何错误或有任何改进建议,请随时告诉我。非常感谢您读到这里。你们太棒了!
文章来源:https://dev.to/iggredible/lazy-loading-with-intersectionobserver-api-3d6h
