IntersectionObserver API学习总结

一、IntersectionObserver 是什么?

IntersectionObserver 是浏览器原生提供的一个构造函数,它可以自动"观察"我们的元素是否可见,本质是判断目标元素与可见区域的交叉比例,所以也被称为"交叉观察器"。

官网的解释:IntersectionObserver 接口提供了一种异步观察目标元素与其祖先元素或顶级文档视窗 (viewport) 交叉状态的方法。祖先元素与视窗 (viewport) 被称为根 (root)。

通俗的说,就是我们可以使用 IntersectionObserver 接口来观察一个元素,观察它是否进入了可视区,这个可视区可以是相对于视窗或者是祖先元素。

【注意】 Intersection Observer API 无法提供重叠的像素个数或者具体哪个像素重叠,他的更常见的使用方式是------当两个元素相交比例在 N% 左右时,触发回调,以执行某些逻辑。

二、用法:

因为它是一个构造函数,所以我们使用 new 的方式实例化一个 IntersectionObserver 对象。

const observer = new IntersectionObserver(callback, options);

它接受两个参数:

(1)callback:回调函数,当元素的可见性发生变化的时候触发或者第一次监听目标元素的时候触发;

(2)options:一些配置项参数,可以用来配置根元素、什么时候触发回调等等(该参数可选)。

三、API 的参数:

(一)callback 参数

是一个回调函数,在目标元素的可见性发生变化或者第一次监听目标元素时触发。

js 复制代码
const observer = new IntersectionObserver((entries) => {

  console.log(entries);

});

observer.observe(document.querySelector(".box"));

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

【注意】 callback 回调函数是在主线程中运行的,如果有一些耗时的操作需要执行,建议使用 Window.requestIdleCallback() 方法---在浏览器空闲时期被调用。

IntersectionObserverEntry 对象

提供目标元素的信息,一共有以下属性:

每个属性的含义:

属性值 说明
1 boundingClientRect 返回目标元素的边界信息,边界的计算方式与Element.getBoundingClientRect()相同
2 intersectionRatio 返回 intersectionRect 与 boundingClientRect 的比例值
3 intersectionRect 用来描述根和目标元素的相交区域
4 isIntersecting 返回一个布尔值,如果目标元素与交叉区域观察者对象 (intersection observer) 的根相交,则返回true;如果返回 true, 则 IntersectionObserverEntry 描述了变换到交叉时的状态;如果返回 false, 那么可以由此判断,变换是从交叉状态到非交叉状态。意思就是我们的目标元素当前是否可见
5 isVisible 我发现只有 chrome 才会返回这个属性,其他浏览器不会返回,值一直为 false
6 rootBounds 根元素的矩形信息,没有指定根元素就是当前视窗的矩形信息
7 target 观察的目标元素
8 time 返回一个记录从 new IntersectionObserver()的时间到交叉被触发的时间的时间戳,单位为毫秒

列出六种可能的情况:

所有区域均被 Intersection Observer API 当做一个矩形看待。如果元素是不规则的图形也将会被看成一个包含元素所有区域的最小矩形,

相似的,如果元素发生的交集部分不是一个矩形,那么也会被看作是一个包含他所有交集区域的最小矩形。

可以把图1到图5看成向上滚动页面的过程:

(图1)

(图2)

(图3)

(图4)

(图5)

(图6)

(二)options 对象

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

(1)threshold: 可以是单一的 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 元素中时候 回调才会被执行。

js 复制代码
const observer = new IntersectionObserver(
  (entries) => {
    console.log(entries);
  },
  {
    threshold: \[0, 0.25, 0.5, 0.75, 1], //表示当目标元素 0%、25%、50%、75%、100% 可见时,会触发回调函数。
  }
);

(2)root

用来指定根 (root) 元素,用于检查目标的可见性。必须是目标元素的父级元素。如果未指定或者为 null,则默认为浏览器视窗。

js 复制代码
const observer = new IntersectionObserver(
  (entries) => {
    console.log(entries);
  },
  {
    root: document.querySelector(".root"),
  }
);

(3)rootMargin

根 (root) 元素的外边距。类似于 CSS 中的 margin 属性,比如 "10px 20px 30px 40px" (top, right, bottom, left)。如果有指定 root 参数,则 rootMargin 也可以使用百分比来取值。该属性值是用作 root 元素和 target 发生交集时候的计算交集的区域范围,使用该属性可以控制 root 元素每一边的收缩或者扩张。默认值为'0px 0px 0px 0px'。

js 复制代码
const observer = new IntersectionObserver(
  (entries) => {
    console.log(entries);
  },
  {
    rootMargin: "100px 100px 100px 100px",
  }
);

四、API 的方法

(1)observe()

在创建完 observer 后需要给定一个目标元素进行观察,每当目标元素满足在创建 observer 时传入的 threshold 值,回调函数就会被执行。

observer.observe(document.querySelector(".box"));

(2)unobserve()

使 IntersectionObserver 停止对某个目标元素的观察。

observer.unobserve(document.querySelector(".box"));

(3)takeRecords() 返回所有观察目标的 IntersectionObserverEntry 对象数组,每个对象包含目标元素与根元素每次的相交信息,与观察者回调返回的信息一样。

observer.takeRecords();

(4)disconnect() 使 IntersectionObserver 停止对所有的目标元素可见性变化的观察。

observer.disconnect();

五、应用及示例

(1)图片懒加载--当图片滚动到可见区时才加载

示例: 懒加载示例

(2)内容无限滚动--滚动到接近内容底部时加载更多

示例: 无限滚动

(3)在用户看见某个区域时执行任务或播放动画

执行任务--比如做埋点或者 toast 或者播放音视频等等。

示例: 播放动画

六、对标微信小程序开发

(1)wx.createIntersectionObserver(自定义组件实例,[options])

new IntersectionObserver(callback, options)一样创建并返回一个 IntersectionObserver 对象实例。

  • observeAll 属性如果传入 true,则相当于对每个目标元素都调用一次 IntersectionObserver.observe();

  • thresholds 属性对标 new IntersectionObserver 中 options 参数传入的 threshold 属性;

(2)IntersectionObserver.disconnect()

让 IntersectionObserver 停止对目标元素可见性变化的观察。

(3)IntersectionObserver.observe(string targetSelector, function callback)

  • targetSelector 指定目标元素

    相当于 IntersectionObserver.observe()中传入的目标元素节点

  • callback 监听相交状态变化的回调函数

    new IntersectionObserver(callback, options)中的 callback 一样 当目标元素相当于根元素的可见性发生变化的时候才执行回调

  1. id与dataset ---对标IntersectionObserverEntry 中的目标元素target;

  2. relativeRect ---对标 IntersectionObserverEntry 中的 rootBounds 目标元素的矩形区域信息

(4)IntersectionObserver.relativeTo(string selector, Object margins)

指定参照区域,相当于指定根元素。

selector 用来指定根元素,margins 用来扩展(或收缩)根元素布局区域的边界,相当于 new IntersectionObserver(callback, options)中 options 传入的 margin 属性。

【注意】小程序的参照区域可以不是目标元素的祖先元素,但是IntersectionObserver API中指定的根元素一定是目标元素的祖先元素。

(5)IntersectionObserver.relativeToViewport(Object margins)

指定页面显示区域作为参照区域之一,相当于 new IntersectionObserver(callback, options)中 options 传入的 root 属性为 null 或者不传,使用视口作为根元素。

七、兼容性

目前的主流浏览器都支持。

可以使用 polyfill 来解决兼容性问题。

A polyfill for IntersectionObserver

IntersectionObserver polyfill

八、总结

我们在做监听某个元素出现和隐藏时,可以使用这个 intersectionObserver 来进行观察,避免不断监听页面滚动,提高页面性能,具体如何影响性能,本文暂不拓展。

相关推荐
Dragon Wu1 分钟前
前端 Canvas 绘画 总结
前端
CodeToGym6 分钟前
Webpack性能优化指南:从构建到部署的全方位策略
前端·webpack·性能优化
~甲壳虫7 分钟前
说说webpack中常见的Loader?解决了什么问题?
前端·webpack·node.js
~甲壳虫11 分钟前
说说webpack proxy工作原理?为什么能解决跨域
前端·webpack·node.js
Cwhat13 分钟前
前端性能优化2
前端
熊的猫1 小时前
JS 中的类型 & 类型判断 & 类型转换
前端·javascript·vue.js·chrome·react.js·前端框架·node.js
瑶琴AI前端1 小时前
uniapp组件实现省市区三级联动选择
java·前端·uni-app
会发光的猪。2 小时前
如何在vscode中安装git详细新手教程
前端·ide·git·vscode
别拿曾经看以后~3 小时前
【el-form】记一例好用的el-input输入框回车调接口和el-button按钮防重点击
javascript·vue.js·elementui
我要洋人死3 小时前
导航栏及下拉菜单的实现
前端·css·css3