一、API
IntersectionObserver API :可以自动"观察"元素是否可见,Chrome 51+ 已经支持。其他支持Firefox:55+、Safari:12.1+、Edge:15+、Opera:44+由于可见(visible)的本质是,目标元素与视口产生一个交叉区,所以这个 API 叫做"交叉观察器"。
用法: var io = new IntersectionObserver(callback, option);
IntersectionObserver
是浏览器原生提供的构造函数,接受两个参数:callback
是可见性变化时的回调函数,option
是配置对象(该参数可选)。
// 开始观察
io.observe(document.getElementById('example'));// 停止观察
io.unobserve(element);// 关闭观察器
io.disconnect();
如果要观察多个节点,就要多次调用这个方法。
io.observe(elementA);io.observe(elementB);
二、callback 参数
目标元素的可见性变化时,就会调用观察器的回调函数callback。
一般会触发两次。一次是目标元素刚刚进入视口(开始可见),另一次是完全离开视口(开始不可见)。
var io = new IntersectionObserver(
entries => {
console.log(entries);
}
);//(
entries
)是一个数组,每个成员都是IntersectionObserverEntry对象。如果同时有两个被观察的对象的可见性发生变化,
entries
数组就会有两个成员。
IntersectionObserverEntry 对象
IntersectionObserverEntry
对象提供目标元素的信息,一共有六个属性。
time
:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒target
:被观察的目标元素,是一个 DOM 节点对象rootBounds
:根元素的矩形区域的信息,getBoundingClientRect()
方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
boundingClientRect
:目标元素的矩形区域的信息intersectionRect
:目标元素与视口(或根元素)的交叉区域的信息intersectionRatio
:目标元素的可见比例,即intersectionRect
占boundingClientRect
的比例,完全可见时为1
,完全不可见时小于等于0
三、Option 对象
第二个参数是一个配置对象。它可以设置以下属性。
- threshold:决定了什么时候触发回调函数。它是一个数组,每个成员都是一个门槛值,默认为
[0]
,- root :指定目标元素所在的容器节点(即根元素)。注意,容器元素必须是目标元素的祖先节点。
- rootMargin:定义根元素的
margin,
它使用CSS的定义方法,比如10px 20px 30px 40px
,表示 top、right、bottom 和 left 四个方向的值。
四、注意点
IntersectionObserver API 是异步的,不随着目标元素的滚动同步触发。
规格写明,IntersectionObserver
的实现,应该采用requestIdleCallback()
,即只有线程空闲下来,才会执行观察器。这意味着,这个观察器的优先级非常低,只在其他任务执行完,浏览器有了空闲才会执行。
兼容性问题
if ('IntersectionObserver' in window) {
// 浏览器支持 IntersectionObserver
} else {
// 浏览器不支持 IntersectionObserver
}
五、实例:无限滚动
var intersectionObserver = new IntersectionObserver(
(entries)=>{
// 如果不可见,就返回
if (entries[0].intersectionRatio <= 0) return;
loadItems(10);
console.log('Loaded new items');
}
// 开始观察
intersectionObserver.observe(
document.querySelector('.scrollerFooter')
);
六、优点
更好的性能:传统的监听滚动事件方式可能会导致频繁的计算,影响页面性能。而 IntersectionObserver 是浏览器原生提供的 API,它使用异步执行,可以更高效地监听元素是否进入视口,减少了不必要的计算和性能开销。
减少代码复杂性:IntersectionObserver 可以简化代码逻辑。使用传统的方式监听滚动事件需要手动计算元素的位置、判断元素是否进入视口,以及处理滚动事件的节流等。而通过 IntersectionObserver,只需定义回调函数,在元素进入或离开视口时触发相应操作,大大简化了代码
支持懒加载和无限滚动:IntersectionObserver 可以实现图片懒加载和无限滚动等常见效果。当元素进入视口时,可以延迟加载图片或触发数据请求,避免不必要的资源加载,提升页面加载速度和性能。
更精确的可见性控制:IntersectionObserver 提供了更精确的可见性控制。通过设置合适的阈值(threshold),可以灵活地控制元素与视口的交叉区域达到多少时触发回调。这使得开发者可以根据需求来定义元素何时被认为是进入或离开视口,从而触发相应的操作。
本文参考阮一峰老师的网络日志