元素页面可见性:Intersection Observer API的妙用

293 阅读2分钟

什么是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 )