深入理解 Observer

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

IntersectionObserver

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

常用API

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

基本用法

javascript 复制代码
// 选择需要观察变动的节点
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,表示:当被监听元素完全进入视图在触发观察者的回调函数

常见场景

  • 监听图片懒加载
javascript 复制代码
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,用于监视元素的大小变化,每次大小更改时都会向观察者传递通知。

typescript 复制代码
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 中。

基本用法

javascript 复制代码
// 选择需要观察变动的节点
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:导航的事件,例如页面加载或重新加载。

基本用法

ini 复制代码
function perf_observer(list, observer) {
  console.log(list);
}

const observer = new PerformanceObserver(perf_observer);
observer.observe({ entryTypes: ["measure"] });

常用场景

  • 首次内容绘制
ini 复制代码
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:一般的错误事件。

基本用法

ini 复制代码
const reportingObserver = new ReportingObserver(reports => {
  reports.forEach(report => {
    console.log(report);
  });
});

reportingObserver.observe({ types: ["deprecation", "intervention"] });

原文链接:深入理解 Observer

相关推荐
Jiaberrr1 小时前
前端实战:使用JS和Canvas实现运算图形验证码(uniapp、微信小程序同样可用)
前端·javascript·vue.js·微信小程序·uni-app
everyStudy1 小时前
JS中判断字符串中是否包含指定字符
开发语言·前端·javascript
城南云小白1 小时前
web基础+http协议+httpd详细配置
前端·网络协议·http
前端小趴菜、1 小时前
Web Worker 简单使用
前端
web_learning_3211 小时前
信息收集常用指令
前端·搜索引擎
Ylucius1 小时前
动态语言? 静态语言? ------区别何在?java,js,c,c++,python分给是静态or动态语言?
java·c语言·javascript·c++·python·学习
tabzzz2 小时前
Webpack 概念速通:从入门到掌握构建工具的精髓
前端·webpack
200不是二百2 小时前
Vuex详解
前端·javascript·vue.js
滔滔不绝tao2 小时前
自动化测试常用函数
前端·css·html5
LvManBa2 小时前
Vue学习记录之三(ref全家桶)
javascript·vue.js·学习