前端Observer之MutationObserver

文章类型:Javascript

发布者:hp

发布时间:2024-11-29

一:概述

MutationObserver 是一个浏览器提供的 API,用于监视 DOM 树的变化,包括节点的添加、删除和属性的修改。

替代传统的轮询方式,通过异步回调高效地检测和响应 DOM 变更,避免了性能问题和复杂的实现细节。

通过异步批处理 DOM 变更,减少了对浏览器性能的影响。

精准地监控特定的 DOM 变化类型,避免重复触发事件,提供更高效、灵活的变更检测机制,适用于需要高性能和细粒度监控的场景

二:定义

1:作用:监视 DOM 树的变化

2:应用场景:

动态内容监控:实时检测和响应页面中的动态内容变化,如新增、删除或修改元素。

表单输入监控:跟踪用户在动态表单中的输入变化,用于实时验证或更新表单状态。

自动更新用户界面:在用户界面上自动更新视图或处理变化,如动态加载的数据或实时反馈。

实现自定义组件:在组件内部检测和响应子组件或 DOM 结构的变化,以便进行相应的渲染或处理。

三:使用

1:图解

2:属性

type=>变动的类型。可能的值包括 attributes(属性变动)、characterData(文本内容变动)、childList(子节点变动)。

target=> 发生变动的目标 DOM 节点。

addedNodes=>被添加到 DOM 的节点列表。返回的是一个 NodeList,如果没有添加节点则为空。

removedNodes=>从 DOM 中移除的节点列表。返回的是一个 NodeList,如果没有移除节点则为空。

previousSibling=>变动前目标节点的前一个兄弟节点(对于 childList 类型变动有效)。

nextSibling=>变动前目标节点的后一个兄弟节点(对于 childList 类型变动有效)。

attributeName=> 被修改的属性名称(对于 attributes 类型变动有效)。

attributeNamespace=>被修改属性的命名空间(对于 attributes 类型变动有效)。

oldValue=> 变动前的属性值(对于 attributes 和 characterData 类型变动有效)。

3:使用

第一步:创建一个 MutationObserver 实例

//第一步 创建一个 MutationObserver 实例
const observer = new MutationObserver((mutationsList, observer) => {
  // 遍历所有变动记录
  // mutationsList 是一个 MutationRecord 的数组,包含所有发生的 DOM 变化
  for (const mutation of mutationsList) {
   // 打印每个 MutationRecord 对象的信息
    console.log(mutation);
    // 处理每个变动
    console.log('变动类型:', mutation.type);
    if (mutation.type === 'attributes') {
      console.log(`属性变动 - 属性名: ${mutation.attributeName}, 变动前值: ${mutation.oldValue}`);
    } else if (mutation.type === 'childList') {
      console.log('子节点变动 - 添加的节点:', mutation.addedNodes, '删除的节点:', mutation.removedNodes);
    } else if (mutation.type === 'characterData') {
      console.log(`文本内容变动 - 变动前值: ${mutation.oldValue}`);
    }
  }
});

第二步:配置观察属性

//第二步 配置观察属性
const config = {
  attributes: true,            // 观察属性的变化
  attributeFilter: ['class'],  // 只观察 class 属性的变化
  attributeOldValue: true,     // 获取变动前的属性值
  childList: true,             // 观察子节点的变化
  subtree: true,               // 观察所有后代节点
  characterData: true,         // 观察文本内容的变化
  characterDataOldValue: true  // 获取变动前的文本内容
};

第三步:选择需要观察的Dom元素

const targetNode = document.getElementById('target');

第四步:启动观察

observer.observe(targetNode, config);

第五步:停止观察

observer.disconnect();

四:总结

1:观察大量 DOM 变更时,因为每次变更都会触发回调函数 MutationObserver 可能会引发性能问题

2:MutationObserver 会观察到子节点和后代节点的变更,这可能导致不必要的回调触发