专栏名称: 前端大全
分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯
目录
相关文章推荐
启四说  ·  启四VIP策略网站,有哪些功能?如何使用? ·  14 小时前  
启四说  ·  启四VIP策略网站,有哪些功能?如何使用? ·  14 小时前  
前端早读课  ·  【第3451期】前端 TypeError ... ·  昨天  
江苏司法行政在线  ·  宿迁司法行政人、江苏监狱戒毒民警,给您拜年啦! ·  3 天前  
江苏司法行政在线  ·  宿迁司法行政人、江苏监狱戒毒民警,给您拜年啦! ·  3 天前  
51好读  ›  专栏  ›  前端大全

无限滚动加载数据利器:IntersectionObserver

前端大全  · 公众号  · 前端  · 2024-09-05 10:00

正文


作者:Aplee

https://juejin.cn/post/7389077092137517108

今天和同事讨论时,讨论了 页面滚动加载数据 的事情,正好我去年年底也做过相同的功能,只是当时因为各种原因吧,没有做总结。现在回想起来,只是记得以前做过,在哪个页面实现的,具体实现的方法,确实有点忘记了。记得当时好像也尝试了很多的方法,最后才实现,这里又要吐槽一下自己的笨了。

所以把当时的代码给扒出来,是利用 IntersectionObserver 这个api实现的,然后在网上找了一些资料,准备输出整理一下相关的文档。

好,我们正式开始介绍。

介绍

IntersectionObserver 是一种现代 Web API,它允许开发者异步观察 一个目标元素与其祖先元素或视口(viewport)交叉状态 的变化。这对于实现图片懒加载或无限滚动功能非常有用。

这里我们借用 阮一峰大佬 的图片介绍:

图片来源为: IntersectionObserver API 使用教程 [1]

传统的实现方法是,在监听到 scroll 事件后,调用目标元素(绿色方块)的 getBoundingClientRect() 方法,获取它相对于视口左上角的坐标,然后判断是否在视口内。然而,这种方法的缺点在于由于scroll事件频繁触发,计算量较大,容易导致性能问题。

而现在就可以使用 IntersectionObserver 这个api实现。

具体实现见下文。

API

IntersectionObserver API是一个用于异步监听目标元素与其祖先或视口(viewport)交叉状态的API。它可以有效地观察页面上的元素,特别是在需要实现懒加载(lazy loading)、无限滚动(infinite scrolling)或者特定动画效果时非常有用。

在介绍 IntersectionObserver API之前,我们先介绍一些概念,便于在后面使用。

  1. 目标元素(Target Element) :需要被观察交叉状态的DOM元素。
  2. 根元素(Root Element) :IntersectionObserver的根元素,即用来定义视口的边界。如果未指定,默认为浏览器视口。
  3. 交叉状态(Intersection) :目标元素与根元素或视口相交的部分。可以通过IntersectionObserver的回调函数获取交叉状态的详细信息。
  4. 阈值(Threshold) :一个介于0和1之间的值,用来指定目标元素什么时候被视为“交叉”。例如,一个阈值为0.5表示当目标元素50%可见时触发回调。

基本使用

使用 IntersectionObserver API 的基本步骤如下:

  1. ** 创建一个IntersectionObserver对象 **:
let observer = new IntersectionObserver(callback, options);
  • callback 是一个回调函数,当目标元素与根元素(或视口)交叉状态发生变化时被调用。
  • options 是一个配置对象,用于设置观察选项。
  1. ** 定义一个回调函数,用于处理元素与视窗的交叉状态变化 **:
let




    
 callback = (entries, observer) => {
  entries.forEach(entry => {
    // 处理交叉状态变化
    if (entry.isIntersecting) {
      // 元素进入视窗
    } else {
      // 元素离开视窗
    }
  });
};
  • entries 是一个包含所有被观察目标元素的 IntersectionObserverEntry 对象数组。
  • observer 是调用回调函数的 IntersectionObserver 实例。
  1. ** 指定要观察的目标元素,并开始观察 **:
let targetElement = document.querySelector('.target-element');
observer.observe(targetElement);
  • targetElement 是要观察的目标元素。可以通过选择器、getElementById 等方法获取。
  1. ** 可选:配置IntersectionObserver的行为,包括根元素、根元素的边界和交叉比例的阈值等属性 **:
let options = {
  rootnull// 观察元素的根元素,null表示视窗
  rootMargin'0px'// 根元素的边界
  threshold0.5 // 交叉比例的阈值,0.5表示元素一半进入视窗时触发回调
};
  1. ** 在回调函数中处理元素的交叉状态变化,根据需要执行相应的操作 **。
  2. 停止观察元素(可选)
observer.unobserve(targetElement);
  1. 停止观察所有元素并清除所有观察者(可选)
observer.disconnect();

通过以上步骤,您可以使用IntersectionObserver API来监测元素与视窗的交叉状态,并根据需要执行相应的操作,实现一些常见的交互效果和性能优化。

// 开始观察
io.observe(document.getElementById('example'));

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

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

IntersectionObserver 构造函数 实例返回方法

当你使用 IntersectionObserver 构造函数创建一个观察器实例后,这个实例会携带四个主要方法来管理和操作观察的行为。这些方法包括:

  1. observe(targetElement)

  • 用于开始观察指定的目标元素。一旦目标元素进入或离开视口,观察器就会触发回调函数。
  • unobserve(targetElement)

    • 用于停止观察指定的目标元素。当你不再需要观察某个元素时,可以使用该方法来取消观察。
  • disconnect()

    • 用于停止观察所有目标元素,并将观察器从所有目标元素中移除。当你不再需要观察任何元素时,可以使用该方法来完全关闭观察器。
  • takeRecords()

    • 用于获取当前观察器实例尚未处理的所有交叉记录(Intersection Records)。该方法返回一个数组,包含所有未处理的交叉记录对象。每个交叉记录对象表示一个目标元素与根元素(或根元素的可视窗口)的交叉信息。

    这些方法可以帮助你控制 IntersectionObserver 实例的行为,以及对特定元素进行观察和取消观察。

    // 开始观察
    io.observe(document.getElementById('example'));

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

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

    // 返回所有观察目标的 IntersectionObserverEntry 对象数组
    io.takeRecords();

    entries介绍

    entries 是传递给 IntersectionObserver 回调函数的一个参数,它是一个包含 IntersectionObserverEntry 对象的数组。每个 IntersectionObserverEntry 对象表示一个被观察目标元素的最新交叉状态(即目标元素与根元素或视口的交集)。

    IntersectionObserverEntry 对象

    每个 IntersectionObserverEntry 对象包含了以下重要信息:

    1. time

    • 一个时间戳,表示交叉状态变化的时间戳,精确到毫秒,通常用于性能测量。
  • target

    • 被观察的目标元素,即观察器正在观察的具体 DOM 元素。
  • rootBounds

    • 一个 DOMRectReadOnly 对象,表示根元素的边界框。如果根元素是视口,则表示视口的边界框。
  • boundingClientRect

    • 一个 DOMRectReadOnly 对象,表示目标元素的边界框,即元素在视口中的位置和尺寸。
  • intersectionRect

    • 一个 DOMRectReadOnly 对象, 表示目标元素与视口(或指定的根元素)交叉部分的矩形区域的信息。如果没有交叉,它的值为 {top: 0, bottom: 0, left: 0, right: 0, width: 0, height: 0}
  • intersectionRatio

    • 一个数值,表示目标元素可见部分占自身的比例,取值范围在 0.0 1.0 之间。当元素完全不可见时,值为 0.0 ;当元素完全可见时,值为 1.0
  • isIntersecting

    • 一个布尔值,表示目标元素当前是否与视口(或指定的根元素)交叉。如果元素至少部分可见,则为 true ;否则为 false

    以下是一个简单的示例,演示了如何在 IntersectionObserver 的回调函数中处理 entries 数组:







    请到「今天看啥」查看全文