深入理解 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

相关推荐
mldong4 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排5 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60615 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角6 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!7 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰7 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi8 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen9 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马10 小时前
AI源码分析:拆解模型底层实现逻辑
前端
BillKu10 小时前
全局样式变量:CSS 自定义属性(--border-color)和SCSS 变量($border-color)的说明
javascript·css·scss