Skip to content

Intersection Observer Api

1.IntersectionObserver

IntersectionObserver 接口(从属于 Intersection Observer API

提供了一种异步观察目标元素与其祖先元素或顶级文档交叉状态的方法。其祖先元素或视口被称为根(root)。

此Api可用于以下场景

  • 图片懒加载——当图片滚动到可见时才进行加载
  • 内容无限滚动——也就是用户滚动到接近内容底部时直接加载更多,而无需用户操作翻页,给用户一种网页可以无限滚动的错觉
  • 检测广告的曝光情况——为了计算广告收益,需要知道广告元素的曝光情况
  • 在用户看见某个区域时执行任务或播放动画

1.1 基本语法

js
var ob = new IntersectionObserver(callback[, options]);

var ob = new IntersectionObserver((entries,observer)=>{
    // 回调函数逻辑
},{
    // 配置
});

1.2 参数

callback:当元素可见比例超过指定阈值后,会调用一个回调函数,此回调函数接受两个参数:

  • entries:一个IntersectionObserverEntry对象的数组,每个被触发的阈值,都或多或少与指定阈值有偏差。具体属性值查看下面IntersectionObserverEntry实例属性
  • observer:被调用的IntersectionObserver实例。

options:可选,一个可以用来配置 observer 实例的对象。如果options未指定,observer 实例默认使用文档视口作为 root,并且没有 margin,阈值为 0%(意味着即使一像素的改变都会触发回调函数)。你可以指定以下配置:

  • root监听元素的祖先dom元素Element对象,其边界盒将被视作视口。目标在根的可见区域的的任何不可见部分都会被视为不可见。

  • rootMargin可以扩大或缩小目标元素与根元素重叠面积的判定范围

    • 语法大致和 CSS 中的margin 属性等同; 可以参考 intersection root 和 root margin 来深入了解 margin 的工作原理及其语法。
    • 默认值是"0px 0px 0px 0px"。
    • 例如,当threshold=0,给目标元素添加了100px的rootMargin,则原本目标元素与根元素有1px的重合就会触发回调函数,现在目标元素与根元素相聚100px时就会触发回调
  • threshold:规定了一个监听目标元素与根元素交叉区域的比例值

    • 可以是一个具体的数值或是一组 0.0 到 1.0 之间的数值。
    • 若指定值为 0.0,则意味着监听元素即使与根有 1 像素交叉,此元素也会被视为可见。
    • 若指定值为 1.0,则意味着整个元素都在可见范围内时才算可见。
    • 可以参考阈值来深入了解阈值是如何使用的。阈值的默认值为 0.0。

1.3 实例属性

root

root 属性用来获取当前 intersectionObserver 实例的根元素。

rootMargin

只读属性 rootMargin 是与 CSS 属性margin语法相似的字符串 (string) 对象。在交叉检测开始之前,由rootMargin 规定的矩形的每一边都会被添加至root元素的边框盒 (bounding box (en-US)) 的相应边。例如,这可以让你向外调整边界,使得目标元素被认为是 100% 可见的,即使此元素得一部分长或宽被裁剪,或者在边缘过于靠近根边框盒边界的情况下,将目标视为部分隐藏。

设置方法和css设置margin一致

thresholds

只读阈值属性返回在使用 IntersectionObserver() 实例化观察器时指定的交集**阈值**列表。如果在实例化对象时仅提供一个阈值比率,这将是一个包含该单个值的数组。

1.4 实例方法

disconnect()

作用:终止对所有目标元素可见性变化的观察。

语法

js
var ob = new IntersectionObserver(callback[, options]);
ob.disconnect();

observe()

作用:向 IntersectionObserver 对象监听的目标集合添加一个dom元素。

语法

js
var ob = new IntersectionObserver(callback);
ob.observe(document.getElementById("elementToObserve"));

unobserve()

命令IntersectionObserver停止对一个元素的观察

js
var ob = new IntersectionObserver(callback);
ob.observe(document.getElementById("elementToObserve"));

/* ... */

ob.unobserve(document.getElementById("elementToObserve"));

2.IntersectionObserverEntry

IntersectionObserverEntry 接口 (从属于 Intersection Observer API ) 描述了目标元素与其根元素容器在某一特定过渡时刻的交叉状态。

IntersectionObserverEntry 的实例作为 entries 参数被传递到一个 IntersectionObserver 的回调函数中; 此外,这些对象只能通过调用IntersectionObserver.takeRecords() 来获取。

2.1 实例属性

boundingCientRect

只读属性,返回一个DOMRect对象,该属性实质上描述了一个描述 包含整个目标元素的最小矩形。

包含此dom元素的left、right、top、bottom、width、height、x、y属性

intersectionRatio

返回观察元素与根元素面积面积相交的比率,值在0.0~1.0之间

  • 若目标元素与根元素一点都不相交,则为0
  • 若目标元素与根元素完全相交,则为1

intersectionRect

IntersectionObserverEntry 接口的 read-only intersectionRect 属性是一个 DOMRectReadOnly 对象,它描述最小的矩形 包含当前在 中可见的目标元素的整个部分 交集根。

isIntersecting

只读属性,目标元素与根元素是否相交,返回布尔值

js
const ob = new IntersectionObserver(
    (entries, observe) => {
        for (let key of entries) {
            if (key.isIntersecting) {
                console.log('目标元素与根元素已相交')
                ob.unobserve(key.target);
            }
        }
    },
    {
        threshold: 0,
    }
);

target

指定目标元素的dom元素,与document.querySelector获取的一样

可通过target属性设置dom元素的样式、标签属性等

ime

目标元素与根元素相交的时间,ms为单位

3.实现图片懒加载

js
const ob = new IntersectionObserver(
    (entires) => {
        for(const entry of entires){
            if(entry.isIntersecting){
                const img=entry.target
                img.src=img.dataset.src
                ob.unobserve(img)
            }
        }
    },
    {
        threshold: 0,
    }
);
const imgs=document.querySelectorAll('img[data-src]')
imgs.forEach((item)=>{
    ob.observe(item)
})

MIT Licensed