一些比较方便的 DOM 监测的 API。
一个 Observer 实例具备的实例方法:
- observe。向监听的目标集合添加一个元素。
- unobserve。停止对一个元素的观察。
- disconnect。终止对所有目标元素的观察。
- …
一、IntersectionObserver
提供了一种异步检测目标元素与祖先元素或视口相交情况变化的方法。
示例,检测目标元素与浏览器视窗是否完全相交:
// 定义一个Observer
let options = {
root: null, // document.querySelector("#parent")
rootMargin: "0px",
threshold: 1.0, // [0, 0.25, 0.5, 0.75, 1]
};
let observer = new IntersectionObserver(callback, options);
// 使用用Observer监测目标元素
let target = document.querySelector("#target");
observer.observe(target);
ResizeObserver Constructor
new ResizeObserver(callback)
,构造器接收两个参数:
callback。回掉函数,当检测到相交时触发
options。配置相交规则
- root。指定与目标元素进行比对的父元素
- 当值为 null,则认为是浏览器视窗。
- 值为 HTMLElement
- rootMargin。外边距。
- threshold。指定
callback
触发的时机- 值为数组,如 0.5,即可见程度为 50% 时触发一次回调。
- 值为数组时,如[0, 0.25, 0.5, 0.75, 1],即可见程度每多 25% 就触发一次回调。
使用场景
- 图片懒加载——当图片滚动到可见时才进行加载
- 内容无限滚动——也就是用户滚动到接近内容底部时直接加载更多,而无需用户操作翻页,给用户一种网页可以无限滚动的错觉
- 检测广告的曝光情况——为了计算广告收益,需要知道广告元素的曝光情况
- 在用户看见某个区域时执行任务或播放动画
二、ResizeObserver
Resize Observer API 提供了一种高性能的机制,通过该机制,代码可以监视元素的大小更改,并且每次大小更改时都会向观察者传递通知。
示例,监控两个元素的大小变化:
<div id="box">
<div id="inner"></div>
</div>
const box = document.querySelector("#box");
const inner = document.querySelector("#inner");
const observer = new ResizeObserver((entries, observer) => {
console.log(entries);
console.log(observer);
});
observer.observe(box);
observer.observe(inner);
ResizeObserver Constructor
new ResizeObserver(callback)
,构造器接收的 callback 接收两个参数:
- entries。一个
ResizeObserverEntry
对象数组,可以用于获取每个元素改变后的新尺寸。 - observer。观察者对象自身
使用场景
- 媒体适配优化
- 自适应布局
- 窗口变化监测
- REM 重置
三、PerformanceObserver
用于监测性能度量事件,在浏览器的性能时间轴记录新的 performance entry 的时候将会被通知。
示例:
function perf_observer(list, observer) {
// Process the "measure" event
// 处理 "measure" 事件
}
var observer = new PerformanceObserver(perf_observer);
observer.observe({ entryTypes: ["measure"] });
PerformanceObserver Constructor
new PerformanceObserver(callback)
,构造器接收的 callback 接收两个参数:
- list。性能观察条目列表
- obj。观察者对象自身
支持的性能观察列表
使用代码PerformanceObserver.supportedEntryTypes
检测浏览器支持的类型。
// chrome中执行Code,查看输出结果
PerformanceObserver.supportedEntryTypes;
// ['back-forward-cache-restoration', 'element', 'event', 'first-input', 'largest-contentful-paint', 'layout-shift', 'longtask', 'mark', 'measure', 'navigation', 'paint', 'resource', 'visibility-state']
使用场景
LCP(Largest Contentful Paint),最大内容绘制
const observer = new PerformanceObserver((list) => {
let perfEntries = list.getEntries();
console.log(perfEntries);
});
observer.observe({
entryTypes: ["largest-contentful-paint", "longtask"],
});
四、MutationObserver
MutationObserver 接口提供了监视对 DOM 树所做更改的能力。它被设计为旧的 Mutation Events 功能的替代品,该功能是 DOM3 Events 规范的一部分。
示例,检测目标元素的属性、子节点、所有后代节点的变化:
const observer = new MutationObserver(function (mutationsList, observer) {
for (let mutation of mutationsList) {
console.log(mutation.type, "changed");
}
});
const targetNode = document.getElementById("box");
observer.observe(targetNode, {
attributes: true,
childList: true,
subtree: true,
});
MutationObserver Constructor
new MutationObserver(callback)
,构造器接收的 callback 接收两个参数:
- mutationsList。所有被触发改动的 MutationRecord 对象数组
- observer。观察者对象自身
支持观测类型:
- subtree。当为 true 时,将会监听以 target 为根节点的整个子树。包括子树中所有节点的属性,而不仅仅是针对 target。
- childList。当为 true 时,监听 target 节点中发生的节点的新增与删除(同时,如果 subtree 为 true,会针对整个子树生效)。
- attributes。当为 true 时观察所有监听的节点属性值的变化。
- attributeFilter。一个用于声明哪些属性名会被监听的数组。如果不声明该属性,所有属性的变化都将触发通知。
- attributeOldValue。当为 true 时,记录上一次被监听的节点的属性变化;
- characterData。当为 true 时,监听声明的 target 节点上所有字符的变化。
- characterDataOldValue。当为 true 时,记录前一个被监听的节点中发生的文本变化。
五、ReportingObserver
处于实验阶段的 API。用于收集、访问报告。
链接
- [^1] IntersectionObserver
- [^2] IntersectionObserver Constructor
- [^3] ResizeObserver
- [^4] ResizeObserver Constructor
- [^5] PerformanceObserver
- [^6] PerformanceEntry.entryType
- [^7] MutationObserver
- [^9] ReportingObserver
- [^10] ReportingObserverOptions