IntersectionObserver API 用法(监控元素与根元素交叉,图片懒加载)

212 阅读2分钟

IntersectionObserver API 用法(监控元素与根元素交叉)

基本用法

  1. 创建观察器

    使用 IntersectionObserver 构造函数创建一个观察器实例。构造函数接收两个参数:

    • 回调函数:当目标元素的交叉状态发生变化时,这个回调函数会被调用。
    • 配置对象(可选):用于配置观察器的行为。
    const observer = new IntersectionObserver(callback, options);
    
  2. 观察目标元素

    使用 observe 方法开始观察一个目标元素。

    const target = document.querySelector('.target-element');
    observer.observe(target);
    
  3. 停止观察

    使用 unobserve 方法停止观察一个目标元素。

    observer.unobserve(target);
    

    或者使用 disconnect 方法停止观察所有目标元素。

    observer.disconnect();
    

回调函数

回调函数接收两个参数:

  • entries:一个 IntersectionObserverEntry 对象的数组,每个对象表示一个目标元素的交叉状态变化。
  • observer:调用回调函数的 IntersectionObserver 实例。

IntersectionObserverEntry 对象包含以下属性:

  • boundingClientRect:目标元素的边界矩形。
  • intersectionRect:目标元素与根元素的交叉矩形。
  • intersectionRatio:目标元素与根元素的交叉比例(0.0 到 1.0)。
  • isIntersecting:目标元素是否与根元素交叉。
  • rootBounds:根元素的边界矩形。
  • target:目标元素。
  • time:交叉状态变化的时间戳。
const callback = (entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      console.log('元素进入视口');
    } else {
      console.log('元素离开视口');
    }
  });
};

配置对象

配置对象可以包含以下属性:

  • root:用作视口的元素,必须是目标元素的祖先元素。如果为 null,则使用顶级文档的视口。
  • rootMargin:类似于 CSS 的 margin 属性,用于扩展或缩小根元素的边界。例如,"10px 20px 30px 40px"
  • threshold:一个数字或数组,表示交叉比例的阈值。当目标元素的交叉比例达到或超过这些阈值时,回调函数会被调用。例如,0.5 表示当目标元素 50% 进入视口时触发回调。
const options = {
  root: null,
  rootMargin: '0px',
  threshold: [0, 0.5, 1]
};

示例

以下是一个简单的懒加载图片的示例:

const lazyImages = document.querySelectorAll('.lazy-image');
​
const observer = new IntersectionObserver((entries, observer) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      const img = entry.target;
      img.src = img.dataset.src;
      img.classList.remove('lazy-image');
      observer.unobserve(img);
    }
  });
}, {
  rootMargin: '0px',
  threshold: 0.1
});
​
lazyImages.forEach(img => {
  observer.observe(img);
});

在这个示例中,当图片元素进入视口时,会将其 src 属性设置为 data-src 的值,并停止观察该元素。

注意事项

  • 性能IntersectionObserver 是异步的,不会阻塞主线程,因此性能较好。
  • 兼容性IntersectionObserver 在现代浏览器中得到了广泛支持,但在旧版浏览器中可能需要使用 polyfill。
  • 精度IntersectionObserver 的精度受到浏览器渲染引擎的影响,可能会有一些延迟。

总结

IntersectionObserver 是一个非常强大的工具,可以简化许多与视口相关的交互逻辑。通过合理使用,可以显著提升网页性能和用户体验。