IntersectionObserver细节研究

519 阅读3分钟

IntersectionObserver 是用于检测元素之间相互交叉重叠的 API,经常用来监听元素的出现和消失。

MDN:developer.mozilla.org/zh-CN/docs/…

虽然 MDN 中描述了基本用法,但是有很多细节不明了,本篇文章将仔细研究一些使用过程中的细节。

实验使用的实例代码大致为如下,即观察一个 DIV 元素和视口的重叠:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body style="height: 200vh">
    <div id="target" style="width: 50vw; height: 50vw; background-color: black"> </div>

    <script>
      let div = document.querySelector('#target')
      let intersectionObserver = new IntersectionObserver(entries => {
        let entry = entries[0]

        console.table([
          ['intersectionRatio', entry.intersectionRatio],
          ['isIntersecting', entry.isIntersecting]
        ])
      })
      intersectionObserver.observe(div)
    </script>
  </body>
</html>

参数

在调用构造函数时,可以传递参数threshold来配置回调函数触发的时机。

关于这个参数,MDN 是这样描述的:

可以是单一的 number 也可以是 number 数组,target 元素和 root 元素相交程度达到该值的时候 IntersectionObserver 注册的回调函数将会被执行。如果你只是想要探测当 target 元素的在 root 元素中的可见性超过50%的时候,你可以指定该属性值为0.5。如果你想要 target 元素在 root 元素的可见程度每多25%就执行一次回调,那么你可以指定一个数组 [0, 0.25, 0.5, 0.75, 1]。默认值是0 (意味着只要有一个 target 像素出现在 root 元素中,回调函数将会被执行)。该值为1.0含义是当 target 完全出现在 root 元素中时候 回调才会被执行。

简单来说,就是重叠比例刚大于或刚小于这个值时,回调函数被触发,也可以理解为回调函数触发的断点。

默认值

默认值是0。在这种情况下,只有当元素与视口从没重叠到有重叠和从有重叠到没重叠的变换时,才会触发回调。

1

如果设置为1,那么只有当元素与视口从部分重叠到完全重叠和从完全重叠到部分重叠的变换时,才会触发回调。

数组

可以传递一个包含多个0到1之间的数字的数组,这样在多个断点上,回调函数都会被触发。

示例:

let intersectionObserver = new IntersectionObserver(callback, { threshold: [0, 1] })

回调

当目标元素和参考元素发生重叠比例变化时,根据配置会触发回调函数并传递回调数据。

数据

我先来看下回调函数传递的数据中比较常用的两个:

  • intersectionRatio:重叠比例
  • intersecting:布尔值。返回 true 表示变换到从非交叉到交叉,返回 false表示变换是从交叉到非交叉

需要注意的事,intersectionRatio表示回调触发时的实际重叠比例,不是构造函数参数中的threshold值。

时机

监听

当调用Intersection.observe时,回调函数会被立即触发,无论当前重叠情况如何,即使元素还没有挂载到文档。

挂载和卸载

元素挂载到文档时,如果已经开始监听那么回调函数被触发。

滚动

文档滚动时,包括window.scrollTowindow.scrollBy,回调函数可能触发。

style

当元素的style变化并导致元素位置等属性变化时,回调函数可能触发。

主要包括:

  • display
  • position,left,right,top,bottom
  • transform