Mutation Observer API 详解

简介: Mutation Observer 提供了监视对 DOM 树所做更改的能力。它被设计为旧的 Mutation Events 功能的替代品,该功能是 DOM3 Events 规范的一部分。

MDN 对Mutation Observer 的描述如下:

Mutation Observer 提供了监视对 DOM 树所做更改的能力。它被设计为旧的 Mutation Events 功能的替代品,该功能是 DOM3 Events 规范的一部分。

换言之,这就是一个 DOM元素变化的监听器,当被观察的目标 DOM 发生改变时就可以执行指定的逻辑。

首先我们可以看一下Mutation Observer的结构

1682518075(1).png

MutationObserver是一个构造函数,他的实例会有 disconnect、observe和 takeRecords 三个方法


constructor


构造函数接收一个函数,用于在 DOM 变化时执行,该函数有两个参数一个是描述所有被触发改动的 MutationRecord 对象数组,另一个是调用该函数的 MutationObserver 对象

function DOMHandler(mutationList, observer) {
  mutationList.forEach((mutation) => {
    switch(mutation.type) {
      case 'childList':
        // 从树上添加或移除一个或更多的子节点
        console.log('结点变更')
        break;
      case 'attributes':
        // mutation.target 中某节点的一个属性值被更改
        console.log('属性变更')
        break;
    }
  });
}
const observer = new MutationObserver(DOMHandler)
复制代码


observe


mutationObserver.observe(target[, options])

  • target: DOM 树中的一个要观察变化的 DOM Node (可能是一个 Element),或者是被观察的子节点树的根节点。
  • options: 一个可选的MutationObserverInit 对象,此对象的配置项描述了 DOM 的哪些变化应该提供给当前观察者的 callback(MDN 说是可选,但是在 chrome 控制台执行时报错必须有至少一个配置项)。
const node1 = document.getElementById('box')
observer.observe(node1, {attributes: true})
node1.setAttribute('name', '张三')
复制代码

然后我们来在元素面板给node1 添加一个属性,此时属性变更触发了回调

1682518095(1).png


disconnect


阻止 MutationObserver 实例继续接收的通知,直到再次调用其 observe() 方法,该观察者对象包含的回调函数都不会再被调用。

observer.disconnect()
node1.setAttribute('name', 'king')
复制代码

调用之后再元素版本修改属性都不会再次触发之前的回调


takeRecords


返回已检测到但尚未由观察者的回调函数处理的所有匹配 DOM 更改的列表,使变更队列保持为空。

observer.observe(node, {attributes: true})
node.setAttribute('name', 'king')
const notices = observer.takeRecords()
复制代码

1682518123(1).png

由此可以看出,DOM 变化之后并不是立即通知执行回调,而是等主线程代码执行完毕再通知,所以 takeRecords 可以将通知提前拦截。

附:observe可接受的 options

属性 说明 默认值
attributes 设为 true 以观察受监视元素的属性值变更。 默认值为 false。
attributeFilter 要监视的特定属性名称的数组。如果未包含此属性,则对所有属性的更改都会触发变动通知。 无默认值。
characterData 设为 true 以监视指定目标节点或子节点树中节点所包含的字符数据的变化。 无默认值
childList 设为 true 以监视目标节点(如果 subtree 为 true,则包含子孙节点)添加或删除新的子节点。 默认值为 false。
subtree 的其他值也会作用于此子树下的所有节点,而不仅仅只作用于目标节点。 默认值为 false。


应用场景


Mutation Observer 主要用在需要监听用户是否违规操作 DOM 的场景, 以水印为例, 监听用户是否私自把页面的水印 DOM 进行删除, 如果触发了事件则对水印进行复原

首先创建一个带有水印的页面,生成水印的代码比较长,就不贴在这里了,有需要的可以联系我私发

1682518147(1).png

框选出来的元素就是水印的容器,如果删除掉这个 DOM 元素我们的水印就会被清除

1682518164(1).png

如果用户有一定的网页知识就会打开 F12 通过开发者工具来删除水印,那么我们的工作就白做了,这时候就可以使用Mutation Observer来监听 DOM 的操作了。

window.onload = function () {
  loadMark(settings); // 加载水印
  function DOMHandler(mutationList, observer) {
    mutationList.forEach((mutation) => {
      const { target, nextSibling, removedNodes } = mutation;
      if (mutation.removedNodes.length) { // 如果列表不为空说明触发操作的动作是删除
        if (nextSibling) { // 如果存在下一个相邻子节点执行插入
          console.log('恢复被删除的节点');
          target.insertBefore(removedNodes[0], nextSibling)
        } else { // 直接添加到 target 的末尾
          target.appendChild(removedNodes[0])
        }
      }
    });
  }
  const observer = new MutationObserver(DOMHandler)
  const node = document.body
  observer.observe(node, { attributes: true, childList: true, subtree: true })
};
复制代码

我们在加载完水印之后创建了一个监听器,并且监听了 body 元素(因为我们的水印元素是 body 的直接子元素,如果直接监听刚才的水印元素,删除这个元素并不会触发监听器)。

首先根据 mutation 的 removedNodes字段判断是否进行了删除操作,如果是删除操作再根据是否有下一个相邻节点来判断节点恢复的位置,如果存在相邻节点就在其前面插入被删除的节点,否则直接在末位追加。

实现的效果如下

相关文章
|
JavaScript API
MutationObserver API
MutationObserver API
72 0
|
JavaScript 前端开发 API
45、Mutation Observer API
Mutation Observer API 用来监视 DOM 变动。DOM 的任何变动,比如节点的增减、属性的变动、文本内容的变动,这个 API 都可以得到通知。
260 0
|
12天前
|
JSON API 数据格式
淘宝 / 天猫官方商品 / 订单订单 API 接口丨商品上传接口对接步骤
要对接淘宝/天猫官方商品或订单API,需先注册淘宝开放平台账号,创建应用获取App Key和App Secret。之后,详细阅读API文档,了解接口功能及权限要求,编写认证、构建请求、发送请求和处理响应的代码。最后,在沙箱环境中测试与调试,确保API调用的正确性和稳定性。
|
24天前
|
供应链 数据挖掘 API
电商API接口介绍——sku接口概述
商品SKU(Stock Keeping Unit)接口是电商API接口中的一种,专门用于获取商品的SKU信息。SKU是库存量单位,用于区分同一商品的不同规格、颜色、尺寸等属性。通过商品SKU接口,开发者可以获取商品的SKU列表、SKU属性、库存数量等详细信息。
|
25天前
|
JSON API 数据格式
店铺所有商品列表接口json数据格式示例(API接口)
当然,以下是一个示例的JSON数据格式,用于表示一个店铺所有商品列表的API接口响应
|
1月前
|
编解码 监控 API
直播源怎么调用api接口
调用直播源的API接口涉及开通服务、添加域名、获取API密钥、调用API接口、生成推流和拉流地址、配置直播源、开始直播、监控管理及停止直播等步骤。不同云服务平台的具体操作略有差异,但整体流程简单易懂。
|
15天前
|
JSON API 数据安全/隐私保护
拍立淘按图搜索API接口返回数据的JSON格式示例
拍立淘按图搜索API接口允许用户通过上传图片来搜索相似的商品,该接口返回的通常是一个JSON格式的响应,其中包含了与上传图片相似的商品信息。以下是一个基于淘宝平台的拍立淘按图搜索API接口返回数据的JSON格式示例,同时提供对其关键字段的解释
|
1月前
|
人工智能 自然语言处理 PyTorch
Text2Video Huggingface Pipeline 文生视频接口和文生视频论文API
文生视频是AI领域热点,很多文生视频的大模型都是基于 Huggingface的 diffusers的text to video的pipeline来开发。国内外也有非常多的优秀产品如Runway AI、Pika AI 、可灵King AI、通义千问、智谱的文生视频模型等等。为了方便调用,这篇博客也尝试了使用 PyPI的text2video的python库的Wrapper类进行调用,下面会给大家介绍一下Huggingface Text to Video Pipeline的调用方式以及使用通用的text2video的python库调用方式。
|
1月前
|
JSON JavaScript API
(API接口系列)商品详情数据封装接口json数据格式分析
在成长的路上,我们都是同行者。这篇关于商品详情API接口的文章,希望能帮助到您。期待与您继续分享更多API接口的知识,请记得关注Anzexi58哦!
|
25天前
|
JSON 前端开发 JavaScript
API接口商品详情接口数据解析
商品详情接口通常用于提供特定商品的详细信息,这些信息比商品列表接口中的信息更加详细和全面。以下是一个示例的JSON数据格式,用于表示一个商品详情API接口的响应。这个示例假定API返回一个包含商品详细信息的对象。
下一篇
无影云桌面