IntersectionObserver 浏览器观察器 API详解

作为前端开发的事件监听,一般常用前端框架自带监听属性,和浏览器对象属性

vue-watch
react-componentdidupdate
浏览器对象属性document.addEventListener

一. IntersectionObserver是浏览器原生提供的构造函数,接受两个参数:callback是可见性变化时的回调函数,option是配置对象(该参数可选)。

// 创建实例 const observer = new IntersectionObserver(callback, option);

// 开始观察element1 observer.observe(element1);

// 关闭观察器 observer.disconnect();

1. callback函数的参数(entries)是一个数组,每个成员都是一个IntersectionObserverEntry对象。举例来说,如果同时有两个被观察的对象的可见性发生变化,entries数组就会有两个成员。

每个IntersectionObserverEntry对象属性含义如下:

  • boundingClientRect:目标元素的矩形区域的信息
  • intersectionRatio:目标元素的可见比例,即intersectionRect占boundingClientRect的比例,完全可见时为1,完全不可见时小于等于0
  • intersectionRect:目标元素与视口(或根元素)的交叉区域的信息
  • rootBounds:根元素的矩形区域的信息,getBoundingClientRect()方法的返回值,如果没有根元素(即直接相对于视口滚动),则返回null
  • isIntersecting:目标元素是否与视口(或根元素)交叉
  • isVisible:并未查阅到相关资料,且经过测试其并不会发生变化
  • target:被观察的目标元素,是一个 DOM 节点对象
  • time:可见性发生变化的时间,是一个高精度时间戳,单位为毫秒

2. Option 对象

IntersectionObserver构造函数的第二个参数是一个配置对象。它可以设置以下属性。

  • root:指定根元素,用于检查目标的可见性。必须是目标元素的父级元素。如果未指定或者为null,则默认为浏览器视窗。
  • rootMargin:根元素的外边距,类似于 CSS 中的margin属性。
  • threshold:目标元素与根元素的交叉比例,可以是单一的 number 也可以是 number 数组,比如,[0, 0.25, 0.5, 0.75, 1]就表示当目标元素 0%、25%、50%、75%、100% 可见时,会触发回调函数。

注意点 IntersectionObserver API 是异步的,不随着目标元素的滚动同步触发。 注册的回调函数将会在主线程中被执行,所以该函数执行速度要尽可能的快。如果有一些耗时的操作需要执行,建议使用 Window.requestIdleCallback() 方法。

二.应用案例

xml 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>IntersectionObserver</title>
  </head>
  <body style="font-size: 24px; text-align: center">
    <div id="container"></div>
    <div id="loadMore">加载中...</div>
  </body>
  <script>
    //懒加载
    const container = document.querySelector("#container");
    const loadMore = document.querySelector("#loadMore");
    let index = 0;

    const loadItems = (count) => {
      [...Array(count).keys()].forEach((key) => {
        const p = document.createElement("P");
        p.innerHTML = `${key + index}`;
        container.appendChild(p);
      });
      index += count;
    };

    const observer = new IntersectionObserver((entries) => {
      entries.forEach(({ isIntersecting }) => {
        if (isIntersecting) {
          loadItems(20);
        }
      });
    });

    observer.observe(loadMore);
  </script>
</html>
相关推荐
CodeCraft Studio19 小时前
纯前端文档编辑组件——Spire.WordJS全新发布
前端·javascript·word·office·spire.wordjs·web文档编辑·在线文档编辑器
前端一课19 小时前
第 32 题:Vue3 Template 编译原理(Template → AST → Transform → Codegen → Render 函数)
前端·面试
前端一课19 小时前
第 33 题:Vue3 v-model 原理(语法糖 → props + emit → modelValue → update:modelValue)
前端·面试
前端一课20 小时前
第 25 题:说一下 Vue3 的 keep-alive 原理?缓存是怎么做的?
前端·面试
前端一课20 小时前
第 30 题:Vue3 自定义渲染器(Custom Renderer)原理- 为什么 Vue 能渲染到 DOM / Canvas / WebGL / 三方平台
前端·面试
前端一课20 小时前
【vue高频面试题】第 23 题:Vue3 自定义指令(directive)完整解析
前端·面试
前端一课20 小时前
第 28 题:Vue3 的 Diff 算法核心原理(双端 Diff、PatchFlags、Block Tree、静态提升)
前端·面试
前端一课20 小时前
【vue高频面试题】第 21 题:Vue3 中的 Slot(插槽)— 基础、原理、使用场景、面试必问点
前端·面试
前端一课20 小时前
第 24 题:Vue3 的组件通信方式(props / emit / v-model / provide-inject / expose / eventBus
前端·面试
前端一课20 小时前
第 22 题:Teleport 的作用、原理和使用场景
前端·面试