Intersection Observer

IntersectionObserver

自动”观察”元素是否可见,Chrome 51+ 已经支持。

API

// 创建并返回观察期实例
let io = new IntersectionObserver(callback, option);

// 开始观察
io.observe(element);

// 停止观察
io.unobserve(element);

io.takeRecords()

// 关闭观察器(停止所有观察)
io.disconnect();

如果需要观察多个节点,需多次调用 observe() 方法。

callback

callback 一般会触发两次,一次是目标元素刚进入视觉区,另一次是完全离开视觉区。

let io = new IntersectionObserve((entries) => {
    // entries 是 包含多个 IntersectionObserverEntry 对象的数组
    console.info(entries);
});

IntersectionObserverEntry 对象

IntersectionObserverEntry 对象提供目标元素的信息

V1

{
  time: 可见性发生变化的时间,是一个高精度时间戳,单位为毫秒,
  target: 被观察的目标元素,是一个 DOM 节点对象,
  rootBounds: 根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null,
  boundingClientRect: 目标元素的矩形区域的信息,
  intersectionRect: 目标元素与视口(或根元素)的交叉区域的信息,
  isIntersecting: Boolean,表示当前目标元素是否可见, 可见为 true
  intersectionRatio: 目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0
}

V2

Intersection Observer V2 中 IntersectionObserverEntry 对象新增了一个属性 isVisible

{
  isVisible: Boolean,表示目标元素在可视区域是否可见(是否被其他元素遮挡)
}

option 对象

V1

{
  threshold: 设定目标元素的可视区域占总区域的比例,达到对应的比例时触发回调函数。它是一个数组,可以包含多个门槛值,默认为[0],
  root: 设置目标元素所在容器,容器内滚动也会影响目标元素的可见性。容器元素必须是目标元素的祖先节点。
  rootMargin: root 元素的 margin 值, 只接受 px 和百分比
}

new IntersectionObserver(
  entries => {/* ... */},
  {
    threshold: [0, 0.25, 0.5, 0.75, 1],
    root: document.querySelector('.container'),
      rootMargin: "20px"  // 将目标元素的监测范围从上下左右四个方向放大了 20px
  }
);

V2

Intersection Observer V2 中 option 参数新增了两个属性 delay 和 trackVisibility

{
  delay: 指定监测到目标元素变更后延迟多久通知(触发回调函数),默认为 0
  trackVisibility: Boolean,表示是否需要监测目标元素在可视区域是否可见(是否被其他元素遮挡),默认为 false
}

注意

IntersectionObserver API 是异步的,不随着目标元素的滚动同步触发。

规格写明,IntersectionObserver 的实现,应该采用 requestIdleCallback(),即只有线程空闲下来,才会执行观察器。这个观察器的优先级非常低,只在其他任务执行完,浏览器有了空闲才会执行。

参考

  • IntersectionObserver’s Coming into View
  • Intersection Observers Explained
  • Intersection Observer
  • caniuse
  • IntersectionObserver API 使用教程
  • IntersectionObserver API
  • Demo
  • IntersectionObserver Doc V2
  • Trust is Good, Observation is Better—Intersection Observer v2