js属性-IntersectionObserver
接下来我们主要认识一下原生JavaScriptAPI-IntersectionObserver这个API
1、认识IntersectionObserver
介绍:IntersectionObserver 是一种原生JavaScript API,用于异步监测元素与其祖先元素(或视口)交叉状态的变化。
也就是说,帮助我们监听某个元素进入或离开视口时的操作
应用场景:懒加载图片、触发动画效果、无限滚动等
优势:与传统的滚动监听方法相比,不需要不断监听滚动事件,而是由浏览器在合适的时候自动触发,减少了性能开销也更高效。
2、基本使用
IntersectionObserver通过一个观察器来监听元素的交叉状态变化。观察器会接收两个主要的参数:
回调函数(callback):当监听的元素的交叉状态发生变化时,会调用此回调函数。
配置对象(options):配置观察器行为的选项,包括根元素、阈值
我们先来看一个代码基本案例,再进行分析
先来写一下我们的结构
javascript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>js-IntersectionObserver</title>
<style>
.tablie {
width: 100%;
height: 400px;
border: 1px solid #ccc;
transition: all 1s;
}
</style>
</head>
<body style="height:100vh;padding: 20px 100px;">
<div style="height: 1600px;width:100%;">
<div class="tablie" id="box">我是测试</div>
<div class="tablie"></div>
<div class="tablie"></div>
<div class="tablie"></div>
<div class="tablie"></div>
<div class="tablie"></div>
<div class="tablie"></div>
<div class="tablie"></div>
</div>
</body>
</html>
添加一下我们的script ,然后我们看看
javascript
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
console.log('元素进入视口', 111);
console.log(entry.target.id);
entry.target.style.backgroundColor = 'lightgreen';
} else {
console.log('元素离开视口', 222);
entry.target.style.backgroundColor = 'lightblue';
}
});
}, {
root: null, // 观察视口,null 代表整个浏览器窗口
rootMargin: '0px', // 视口边缘的额外间距
threshold: 0.5 // 触发回调的交叉比例(0到1之间)
});
const box = document.getElementById('box'); // 获取要观察的元素
observer.observe(box); // 开始观察元素
思路分析
上面的代码的整个过程如下:
先来看看上面整个部分是哪些东西,简单总结一个,其实非常简单(回调函数+配置对象)
javascript
(1) 创建一个IntersectionObserver 实例,并提供一个回调函数来处理元素交叉状态变化。
(2) 配置root等配置
(3) 使用observe() 方法将目标元素添加到观察器中,这里我们是为了观察目标元素,
开始监控 target-element 元素
当其与视口的交叉状态发生变化时,我们就可以调用回调函数。
3、参数
回调函数(callback)
回调函数callback
接收两个参数entries和observer
javascript
new IntersectionObserver((entries, observer) => {})
entries
包含所有被观察元素的 IntersectionObserverEntry 对象数组,所以上面的示例之中我们为什么用forEach
的原因也清晰了。
forEach
中的每个对象都代表一个被观察的元素,有该元素交叉状态信息( isIntersecting(是否与视口交叉)、intersectionRatio(交叉比例)、boundingClientRect(元素的矩形框))等一些属性。
配置对象(options)
先来看看我们配置对象里面的一些属性
root :
观察的根元素,利用这个属性我们可以设置视口元素,默认为 null,表示浏览器窗口。当我们监控一个特定的父容器的视口,可以设置为该容器。
rootMargin:
根元素的边缘间距
javascript
rootMargin: '10px 0px' : 视口上下方向上10px的范围
threshold :
触发回调的交叉比例,设置交叉比例的阈值(数字或数字数组-- 0 到 1 ),代表目标元素与根元素交叉的比例
threshold :0.5
当元素至少有 50% 可见时才触发回调
0.5 :当目标元素有 50% 可见时就触发回调。
[0, 0.5, 1] :当目标元素的可见比例为 0%、50%、100% 时都会触发回调
4、优化和剖析
停止观察目标元素
监听完元素以后可以移除元素,优化性能
javascript
observer.unobserve(target);
entries.forEach(entry => {
if (entry.isIntersecting) {
const loadElement = entry.target;
console.log('元素进入视口', 111);
console.log(loadElement.id);
loadElement.style.backgroundColor = 'lightgreen';
observer.unobserve(loadElement); // 加载完成后停止观察
} else {
console.log('元素离开视口', 222);
entry.target.style.backgroundColor = 'lightblue';
}
});
关闭所有元素
当我们需要完全停止所有的观察,可以使用 disconnect() 方法。
javascript
observer.disconnect();
5、实战应用
图片懒加载
接下来我们尝试一个常见的使用场景,懒加载图片,当图片进入视口时,才加载图片内容
注:**data-src**
图片懒加载具体属性可以查看图片篇
javascript
<img data-src="image1.jpg"class="lazy"alt="Image 1">
<img data-src="image2.jpg"class="lazy"alt="Image 2">
const lazyImages = document.querySelectorAll('.lazy');
// 创建 IntersectionObserver 实例
const observer = new IntersectionObserver((entries, observer) => {
entries.forEach(entry => {
// 当图片进入视口时,加载图片
if (entry.isIntersecting) {
const lazyImage = entry.target;
lazyImage.src = lazyImage.dataset.src; // 使用数据属性加载图片
lazyImage.classList.remove('lazy'); // 移除懒加载类
observer.unobserve(lazyImage); // 加载完成后停止观察该图片
}
});
}, { threshold: 0.1 });
// 观察每个懒加载图片
lazyImages.forEach(image => {
observer.observe(image);
});
分析:
懒加载图片之中,带有 data-src 属性的懒加载图片,图片的真实 src 地址保存在 data-src 中,初始 src 为空或为占位符。
利用 IntersectionObserver,当图片进入视口时,回调函数会被调用,图片的 src 属性会被设置为 data-src 的值,达到懒加载图片。
当图片加载后,移除 lazy 类并停止观察该图片,从而释放资源。