首页 专题 H5案例 前端导航 UI框架

深入理解 Observer

作者:TG 日期: 2024-07-20 字数: 15253 阅读: 208

浏览器为开发者提供了功能丰富的 Observer,在这篇文章中,我们将学习这些常见的浏览器 Observer,剖析它们的作用、用法以及它们在 Web 开发中的应用场景。

IntersectionObserver

IntersectionObserver 用于监听元素在视口中的可见比例变化。

常用API

  • IntersectionObserver(callback[, options]):创建新的实例,传入变动时的回调函数和配置对象。
  • observe(target):开始观察指定目标元素,传入目标元素。
  • unobserve(target):停止观察指定目标元素。
  • disconnect():停止观察,断开与所有目标元素的关联。

基本用法

  • // 选择需要观察变动的节点
  • const target = document.getElementById('some');
  • const options = {
  • root: rootTarget, // 可以是一个祖先级对象,这时,主要的是针对局部的滚动效果。如果构造函数未传入 root 或其值为null,则默认使用顶级文档的视口。
  • rootMargin: '0px', // 视口的偏移值,相当于扩大视口的范围。
  • threshold: 0.5 // 当被观察者进入视口百分之多少时触发观察者
  • };
  • const intersectionObserver = new IntersectionObserver((entries, observer) => {
  • entries.forEach(entry => {
  • console.log(entry);
  • });
  • }, options);
  • // 开始观察目标节点
  • intersectionObserver.observe(target);
  • threshold默认值是0,表示:刚进入时就触发观察者的回调函数;完全离开时,在触发观察的回调
  • 当threshold的值是1,表示:当被监听元素完全进入视图在触发观察者的回调函数

常见场景

  • 监听图片懒加载
  • const observer = new IntersectionObserver(
  • (entries, observer) => {
  • if (entries[0].intersectionRatio > 0.1) {
  • // 存在交叉,出现在视区中
  • }
  • },
  • {
  • threshold: 0.1,
  • }
  • )
  • const target = document.querySelector('img')
  • observer.observe(target)

ResizeObserver

ResizeObserver 是一个 JavaScript API,用于监视元素的大小变化,每次大小更改时都会向观察者传递通知。

  • const resizeObserver = new ResizeObserver((entries: ResizeObserverEntry[]) => {
  • entries.forEach(entry => {
  • // do something...
  • })
  • })
  • resizeObserver.observe(elem)

常用API

  • ResizeObserver(callback):创建新的实例,传入尺寸变化时的回调函数。
  • observe(target):开始观察指定目标元素,传入目标元素。
  • unobserve(target):停止观察指定目标元素。
  • disconnect():停止观察,断开与所有目标元素的关联。

ResizeObserverEntry

  • borderBoxSize:一个对象,当运行回调时,该对象包含着正在观察元素的新边框盒的大小。
  • contentBoxSize:一个对象,当运行回调时,该对象包含着正在观察元素的新内容盒的大小。
  • devicePixelContentBoxSize:一个对象,当运行回调时,该对象包含着正在观察元素的新内容盒的大小(以设备像素为单位)。
  • contentRect:一个对象,当运行回调时,该对象包含着正在观察元素新大小的 DOMRectReadOnly 对象。
  • target:对正在观察 Element 或 SVGElement 的引用

备注:内容盒是放置内容的盒子,即边框盒减去内边距和边框宽度。边框盒包含内容、内边距和边框。

常用场景

  • 监听尺寸变化适配视区

MutationObserver

MutationObserver 用于监听DOM对象的变更,包括节点属性的变化、子节点的增删改等。

常用API

  • MutationObserver(callback):创建新的实例,传入变更时的回调函数。
  • observe(target[, options]):开始观察指定目标节点,传入目标节点和配置对象。
  • disconnect():停止观察,断开与所有目标节点的关联。
  • takeRecords():从 MutationObserver 的通知队列中删除所有待处理的通知,并将它们返回到 MutationRecord 对象的新 Array 中。

基本用法

  • // 选择需要观察变动的节点
  • const targetNode = document.getElementById("some");
  • // 观察器的配置(需要观察什么变动)
  • const config = {
  • attributes: true, // 观察所有监听的节点属性值的变化
  • childList: true, // 监听 target 节点中发生的节点的新增与删除
  • subtree: true, // 监听以 target 为根节点的整个子树。包括子树中所有节点的属性
  • characterData: true // 监听声明的 target 节点上所有字符的变化。
  • };
  • // 当观察到变动时执行的回调函数
  • const callback = function (mutationsList, observer) {
  • console.log(mutationsList);
  • };
  • // 创建一个观察器实例并传入回调函数
  • const observer = new MutationObserver(callback);
  • // 开始观察目标节点
  • observer.observe(targetNode, config);
  • // 之后,可停止观察
  • observer.disconnect();

PerformanceObserver

PerformanceObserver 用于监听浏览器的性能事件,便于处理性能相关信息。

常用API

  • PerformanceObserver(callback):创建新的实例,传入性能事件发生时的回调函数。
  • observe(options):开始观察指定类型的性能事件,传入配置对象,指定entryTypes。
  • disconnect():停止观察,断开与所有性能事件的关联。

常见entryTypes

  • mark:标记时间戳的事件。
  • measure:performance.measure触发的事件。
  • frame:网页渲染的事件。
  • navigation:导航的事件,例如页面加载或重新加载。

基本用法

  • function perf_observer(list, observer) {
  • console.log(list);
  • }
  • const observer = new PerformanceObserver(perf_observer);
  • observer.observe({ entryTypes: ["measure"] });

常用场景

  • 首次内容绘制
  • export function observePaintFCP() {
  • const entryHandler = (list) => {
  • for (const entry of list.getEntries()) {
  • if (entry.name === 'first-contentful-paint') {
  • observer.disconnect();
  • }
  • }
  • };
  • const observer = new PerformanceObserver(entryHandler);
  • observer.observe({ entryTypes: ['paint'] });
  • }

ReportingObserver

ReportingObserver用于监听浏览器报告的事件,例如废弃API,过时特性,网络错误。

常用API

  • ReportingObserver(callback):创建新的实例,传入报告事件发生时的回调函数。
  • observe(options):开始观察指定类型的报告事件,传入配置对象,指定types。
  • disconnect():停止观察,断开与所有报告事件的关联。

常见报告事件类型

  • deprecation:废弃API的事件。
  • intervention:浏览器干预的事件。
  • crash:浏览器崩溃的事件。
  • error:一般的错误事件。

基本用法

  • const reportingObserver = new ReportingObserver(reports => {
  • reports.forEach(report => {
  • console.log(report);
  • });
  • });
  • reportingObserver.observe({ types: ["deprecation", "intervention"] });
目录