使用Intersection Observer API在JavaScript中实现懒加载,无限滚动等功能,而不需要使用复杂的逻辑或导致性能问题。
Intersection Observer API 用于异步观察元素与浏览器视口的交集变化。它使得检测元素的可见性,或者两个元素的相对可见性变得容易,而不会使网站变得缓慢并降低用户体验。本文将介绍关于Intersection Observer的所有内容。
Intersection Observer 的用途
在我们开始探索Intersection Observer API之前,让我们看一下在Web应用程序中使用它的一些常见原因:
1、无限滚动
这是一种Web设计技术,用户向下滚动时不断加载内容。它消除了手动点击分页,并可以提高用户停留时间。
2、懒加载
懒加载是一种设计模式,其中图片或其他内容仅在它们被滚动到用户的视图中时才加载,以提高性能并节省网络资源。
3、基于滚动的动画
这意味着当用户向上或向下滚动页面时,会对元素进行动画处理。有时当达到特定的滚动位置时,动画会完全播放。其他时候,当滚动位置发生变化时,动画中的时间也会发生变化。
4、广告收入计算
我们可以使用Intersection Observer来检测广告何时对用户可见并记录印象,从而影响广告收入。
创建 Intersection Observer
让我们看一下JavaScript中使用Intersection Observer的一个简单用例。
index.js
const observer = new IntersectionObserver((entries) => {
for (const entry of entries) {
const intersecting = entry.isIntersecting;
entry.target.style.backgroundColor = intersecting ? 'blue' : 'orange';
}
});
const box = document.getElementById('box');
observer.observe(box);
回调函数接收一个数组,其中包含IntersectionObserverEntry接口的对象。该对象包含有关当前被Observer观察的元素的交叉相关信息。
每当目标元素与视口相交时,就会调用回调。第一次观察元素时,也会调用回调。
我们使用for...of循环来迭代传递给回调的条目。我们只观察一个元素,因此条目数组将只包含表示框的IntersectionObserverEntry元素,并且for...of循环将只有一个迭代。
IntersectionObserverEntry元素的isIntersecting属性返回一个布尔值,指示元素是否与视口相交。
当isIntersection为true时,这意味着元素正在从不相交转换为相交。但是当它为false时,它表示元素正在从相交转换为不相交。
因此,我们使用isIntersection属性将元素的颜色设置为蓝色,因为它进入视口,并在离开视口时将其设置回黑色。
下面的示例就是上述代码,box 元素进入视口后颜色的颜色变化:
Intersection Observer 参数属性
除了回调函数外,IntersectionObserver()构造函数还接受一个选项对象,用于自定义必须满足的条件以便调用回调函数。
threshold
threshold属性接受介于0和1之间的值,指定必须在视口中可见的元素的百分比,以便调用回调函数。默认情况下,它的值为0,这意味着当元素的单个像素进入视口时,回调将运行一次。
让我们修改我们之前的示例,使用100%的阈值:
index.js
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
const intersecting = entry.isIntersecting;
entry.target.style.backgroundColor = intersecting ? 'blue' : 'black';
}
},
// Threshold is 100%
{ threshold: 1 }
);
const box = document.getElementById('box');
observer.observe(box);
现在,只有在元素的每个像素都可完整见于视口时,改变颜色的回调才会执行。
threshold 还接受多个值,这使得回调在元素通过设置的每个阈值值时触发。
例如:index.js
const threshold = document.getElementById('threshold');
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
const ratio = entry.intersectionRatio;
threshold.innerText = `${Math.round(ratio * 100)}%`;
}
},
// Multiple treshold values
{ threshold: [0, 0.25, 0.5, 0.75, 1] }
);
const box = document.getElementById('box');
observer.observe(box);
我们将5个百分比值作为数组传递给threshold属性,并将每个值显示为元素到达它。为此,我们使用intersectionRatio属性,一个介于0和1之间的数字,表示在视口中的元素的当前百分比。
请注意,所显示的文本并不总是匹配我们的阈值,例如,演示中的0%阈值显示为2%。这是因为当我们快速滚动并到达阈值时,当回调可以触发以更新文本时,我们已经滚动更多的元素超过阈值。
如果我们滚动得更慢,回调就有时间在元素滚过当前阈值之前更新文本。
rootMargin
rootMargin属性可以应用于视口或根元素周围的外边距。它接受与CSS margin属性相同的值,例如10px 20px 30px 40px(上、右、下、左)。边距会增加或缩小 Intersection Observer 观察目标元素与其交叉的视口区域。
这是使用rootMargin属性的示例:
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
const intersecting = entry.isIntersecting;
entry.target.style.backgroundColor = intersecting ? 'blue' : 'black';
}
},
// Root margin 50px from bottom of viewport
{ rootMargin: '50px' }
);
const box = document.getElementById('box');
observer.observe(box);
设置50px的根边距后,视口在交叉方面实际上增加了高度,并且当元素距离视口不到50像素时,回调函数将被调用。
演示中的红线表示观察者观察任何交叉的区域的边界。
我们还可以指定负边距来缩小用于相交的视口区域。
const observer = new IntersectionObserver(
(entries) => {
for (const entry of entries) {
const intersecting = entry.isIntersecting;
entry.target.style.backgroundColor = intersecting ? 'blue' : 'black';
}
},
// Negative margin
{ rootMargin: '-50px' }
);
const box = document.getElementById('box');
observer.observe(box);
现在,当元素的一个像素在视口内超过50像素时,回调被触发。
当元素的一个像素在视口内超过50像素时,它会改变颜色。
root属性
root属性接受一个必须是正在观察的元素的祖先的元素。默认情况下,它为null,这意味着使用视口。你不会经常使用此属性,但当你在页面上有一个可滚动的容器并且想要检查它的某个子元素是否与其相交时,它非常有用。
例如,为了创建本文中的演示,我将root属性设置为页面上的可滚动容器,以便您可以轻松地可视化视口和其外部区域,并更好地理解交叉是如何工作的。
第二个回调参数
Intersection Observer() 的回调函数实际上有两个参数。第一个参数是我们之前讨论过的 entries,第二个参数是正在监听交叉的 Observer 对象。
const observer = new IntersectionObserver((entries, o) => {
console.log(o === observer); // true
});
在回调函数中,这个参数很有用,可以让我们在无法访问 Observer 变量的位置使用回调函数,例如在不同的文件中。
防止内存泄漏
为了避免内存泄漏和性能问题,我们需要在不再需要观察元素时停止观察,例如当它们从 DOM 中删除或在单次基于滚动的动画后。我们可以使用 unobserve() 方法来实现这一点。
new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
doAnim(entry.target);
observer.unobserve(entry.target);
}
});
});
unobserve() 方法以单个元素作为参数,停止观察该元素。还有一个 disconnect() 方法,可以使 Observer 停止观察所有元素。
总结
总之,Intersection Observer 是一个强大的 JavaScript API,可以轻松地检测元素何时与视口或父元素相交。它让我们能够实现惰性加载、基于滚动的动画、无限滚动等功能,而不会引起性能问题和复杂的逻辑。
今天先分享到这里,希望今天的分享对你有所帮助,在你的开发中,别忘记尝试下这个Intersection Observer API。感谢你的阅读,如果你喜欢我的分享,别忘了点赞转发,让更多的人看到,最后别忘记关注「前端达人」,你的支持将是我分享最大的动力,后续我会持续输出更多内容,敬请期待。
https://javascript.plainenglish.io/javascript-intersection-observer-cded4e80a377文章来源:https://www.toymoban.com/news/detail-769263.html
非直接翻译,有自行改编和添加部分,翻译水平有限,难免有疏漏,欢迎指正文章来源地址https://www.toymoban.com/news/detail-769263.html
到了这里,关于JS小知识,Intersection Observer API 使用指南的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!