什么是Intersection Observer API
来看一段MDN的解释:
IntersectionObserver接口 (从属于Intersection Observer API) 提供了一种异步观察目标元素与其祖先元素或顶级文档视窗(viewport)交叉状态的方法。祖先元素与视窗(viewport)被称为根(root)。
当一个IntersectionObserver对象被创建时,其被配置为监听根中一段给定比例的可见区域。一旦IntersectionObserver被创建,则无法更改其配置,所以一个给定的观察者对象只能用来监听可见区域的特定变化值;然而,你可以在同一个观察者对象中配置监听多个目标元素。
一个典型的用法为:
// 当其监听到目标元素的可见部分穿过了一个或多个thresholds时,会执行的指定的回调函数
const onIntersection=(entries)=>{
entries.forEach(entry =>{
//TODO
})
}
// new 一个IntersectionObserver实例,其中onIntersection作为回调传入
const observer = new IntersectionObserver(onIntersection, {
root: elm, // 所监听对象的具体祖先元素。如果未传入值或值为`null`,则默认为整个window的视口。
threshold: [0,0.5,1] // 一个包含阈值的列表, 按升序排列, 列表中的每个阈值都是监听对象的交叉区域与边界区域的比率。当监听对象的任何阈值被越过时,都会触发回调。
})
// 调用IntersectionObserver实例去监测某个DOM节点
observer.observe( dom )
// 停止观测某个DOM节点
observer.unobserve( dom )
在监测元素页面可见性中的应用
图片懒加载这种常见的页面加载优化技术,与对图片在页面/父容器中的可见性密切相关。通常的做法是通过监听window上的scroll事件,在回调函数中将可视区域高度和滚动高度之和与图片的offsetTop做比较,借此判断图片在可视区域中时再加载指定src的图片。 监听scroll事件往往是比较消耗性能的,即便使用了节流等操作也是如此。如果使用Intersection Observer API监测元素页面可见性则会轻松很多。一个大概的懒加载的例子如下:
const imgELm=document.getElementById('my-image')
const realSrc='' //图片真实地址
const onIntersection=(entries)=>{
entries.forEach(entry =>{
//intersectionRatio大于等于0表明监测的图片元素已经进入了视口里
if(entry.intersectionRatio>0){
const img=entry.target //imgELm
//创建一个临时图片
const temp=new Image()
temp.src=realSrc
// 等临时图片加载完毕,再把图片真实地址赋给监测的图片元素
temp.onload=()=>{
img.src=realSrc
}
}
})
}
const observer = new IntersectionObserver(onIntersection, {
root: null,
threshold: [0]
})
observer.observe( imgELm )