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
74 0
|
JavaScript 前端开发 API
45、Mutation Observer API
Mutation Observer API 用来监视 DOM 变动。DOM 的任何变动,比如节点的增减、属性的变动、文本内容的变动,这个 API 都可以得到通知。
263 0
|
8天前
|
人工智能 自然语言处理 API
Multimodal Live API:谷歌推出新的 AI 接口,支持多模态交互和低延迟实时互动
谷歌推出的Multimodal Live API是一个支持多模态交互、低延迟实时互动的AI接口,能够处理文本、音频和视频输入,提供自然流畅的对话体验,适用于多种应用场景。
51 3
Multimodal Live API:谷歌推出新的 AI 接口,支持多模态交互和低延迟实时互动
|
3天前
|
前端开发 API 数据库
Next 编写接口api
Next 编写接口api
|
10天前
|
XML JSON 缓存
阿里巴巴商品详情数据接口(alibaba.item_get) 丨阿里巴巴 API 实时接口指南
阿里巴巴商品详情数据接口(alibaba.item_get)允许商家通过API获取商品的详细信息,包括标题、描述、价格、销量、评价等。主要参数为商品ID(num_iid),支持多种返回数据格式,如json、xml等,便于开发者根据需求选择。使用前需注册并获得App Key与App Secret,注意遵守使用规范。
|
8天前
|
JSON API 开发者
淘宝买家秀数据接口(taobao.item_review_show)丨淘宝 API 实时接口指南
淘宝买家秀数据接口(taobao.item_review_show)可获取买家上传的图片、视频、评论等“买家秀”内容,为潜在买家提供真实参考,帮助商家优化产品和营销策略。使用前需注册开发者账号,构建请求URL并发送GET请求,解析响应数据。调用时需遵守平台规定,保护用户隐私,确保内容真实性。
|
9天前
|
搜索推荐 数据挖掘 API
淘宝天猫商品评论数据接口丨淘宝 API 实时接口指南
淘宝天猫商品评论数据接口(Taobao.item_review)提供全面的评论信息,包括文字、图片、视频评论、评分、追评等,支持实时更新和高效筛选。用户可基于此接口进行数据分析,支持情感分析、用户画像构建等,同时确保数据使用的合规性和安全性。使用步骤包括注册开发者账号、创建应用获取 API 密钥、发送 API 请求并解析返回数据。适用于电商商家、市场分析人员和消费者。
|
19天前
|
JSON API 开发工具
淘宝实时 API 接口丨淘宝商品详情接口(Taobao.item_get)
淘宝商品详情接口(Taobao.item_get)允许开发者获取商品的详细信息,包括基本信息、描述、卖家资料、图片、属性及销售情况等。开发者需注册账号、创建应用并获取API密钥,通过构建请求获取JSON格式数据,注意遵守平台规则,合理使用接口,确保数据准确性和时效性。
|
20天前
|
JSON 安全 API
Python调用API接口的方法
Python调用API接口的方法
86 5
|
20天前
|
JSON 缓存 监控
淘宝商品详情接口(Taobao.item_get)丨淘宝API接口指南
淘宝商品详情接口(Taobao.item_get)允许开发者通过HTTP GET方法获取淘宝商品的详细信息,包括商品ID、价格、库存等。请求需包含key、secret、num_iid等必选参数,支持缓存及多种返回格式。此接口广泛应用于电商数据分析、商品选品、价格监控等领域,提升商家运营效率。
下一篇
DataWorks