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
82 0
|
JavaScript 前端开发 API
45、Mutation Observer API
Mutation Observer API 用来监视 DOM 变动。DOM 的任何变动,比如节点的增减、属性的变动、文本内容的变动,这个 API 都可以得到通知。
271 0
|
19天前
|
JSON 前端开发 搜索推荐
关于商品详情 API 接口 JSON 格式返回数据解析的示例
本文介绍商品详情API接口返回的JSON数据解析。最外层为`product`对象,包含商品基本信息(如id、name、price)、分类信息(category)、图片(images)、属性(attributes)、用户评价(reviews)、库存(stock)和卖家信息(seller)。每个字段详细描述了商品的不同方面,帮助开发者准确提取和展示数据。具体结构和字段含义需结合实际业务需求和API文档理解。
|
4天前
|
搜索推荐 数据挖掘 API
微店商品详情接口(微店API系列)
微店商品详情接口是微店API的重要组成部分,帮助开发者和商家获取商品的详细信息(如标题、价格、库存等),并将其集成到应用程序或数据分析系统中。该接口支持HTTP GET/POST请求,返回JSON/XML格式数据,需通过AppKey和AppSecret进行身份验证和签名加密。应用场景包括商品信息同步、数据分析与市场调研、个性化推荐系统等,助力商业决策和业务拓展。
28 13
|
6天前
|
供应链 数据挖掘 API
1688app 商品详情接口系列(1688API)
1688作为国内知名批发采购平台,提供了一系列商品详情接口(API),助力企业和开发者获取商品基础、价格、库存及供应商信息。通过Python示例代码展示如何调用这些接口,应用场景涵盖采购决策辅助、数据分析与市场调研、电商平台整合及供应链管理系统的优化,为企业和采购商提供有力的数据支持,提升业务效率和竞争力。
43 15
|
13天前
|
JSON 搜索推荐 API
京东店铺所有商品接口系列(京东 API)
本文介绍如何使用Python调用京东API获取店铺商品信息。前期需搭建Python环境,安装`requests`库并熟悉`json`库的使用。接口采用POST请求,参数包括`app_key`、`method`、`timestamp`、`v`、`sign`和业务参数`360buy_param_json`。通过示例代码展示如何生成签名并发送请求。应用场景涵盖店铺管理、竞品分析、数据统计及商品推荐系统,帮助商家优化运营和提升竞争力。
58 23
|
5天前
|
JSON 数据挖掘 开发者
1688 商品评论接口系列(1688API)
1688商品评论接口助力电商数据分析与优化。通过该接口,开发者可获取指定商品的评论数据(如昵称、内容、评分等),支持情感分析和质量反馈收集。接口采用HTTP GET/POST请求,返回JSON格式数据。Python示例代码展示如何调用接口并处理响应。应用场景包括商家产品优化、客户服务提升、市场调研及电商平台数据分析。
|
13天前
|
JSON 缓存 API
解析电商商品详情API接口系列,json数据示例参考
电商商品详情API接口是电商平台的重要组成部分,提供了商品的详细信息,支持用户进行商品浏览和购买决策。通过合理的API设计和优化,可以提升系统性能和用户体验。希望本文的解析和示例能够为开发者提供参考,帮助构建高效、可靠的电商系统。
32 12
|
5天前
|
供应链 数据挖掘 BI
1688 买家订单,订单物流,订单回传接口系列(1688 寻源通 API)
1688作为国内领先的批发采购平台,提供了买家订单、订单物流及订单回传三大API接口,助力企业实现订单管理、物流跟踪和信息反馈的自动化。通过这些接口,企业可以获取订单详情、物流状态,并将处理结果回传至平台,提升运营效率。Python示例代码展示了如何使用这些接口进行数据交互,适用于电商内部管理、物流跟踪及数据分析等场景。
|
11天前
|
供应链 监控 数据挖掘
1688 商品详情接口系列(1688 API)
1688商品详情接口系列(1688 API)是阿里巴巴旗下批发电商平台提供的强大工具,支持开发者、商家获取商品的详细信息。通过商品基本信息、价格库存、图片和描述查询接口,用户可以精准高效地获取商品数据,涵盖电商运营、数据分析、市场调研等领域,极大提升工作效率。示例代码展示了如何使用Python调用这些接口,助力电商平台整合、价格监控、商品展示优化及库存管理等应用场景。