JavaScript MutationObserver 实例讲解
本文详细解析 JavaScript 中的 MutationObserver API,介绍其如何异步监听 DOM 节点增加、删除及属性变更。通过构造函数参数、实例方法 observe/disconnect/takeRecords 以及 MutationRecord 对象属性,结合页面水印防篡改案例,提供完整的代码实现与配置说明。
前言
近期在开发页面水印功能时接触到了 MutationObserver。为何需要它?若不使用该技术,用户可通过随意修改 DOM 来移除系统自带的版权标识(水印),从而使用无水印版本,这违背了设计初衷。MutationObserver 能够实时监听 DOM 变化,一旦检测到水印节点被删除,即可立即重新生成,从而有效防止此类操作。
一、MutationObserver
MutationObserver 构造函数用于监听 DOM 的变化,包括节点增加、删除、属性修改及文本变动等。其主要特点如下:
- 异步触发:仅在 DOM 操作全部结束后才触发回调。
- 批量处理:将 DOM 的变化记录收集到数组中统一处理。
- 灵活监听:可监听所有类型的 DOM 变化,也可指定特定类型进行监听。
通过 MutationObserver 创建实例(如 createObserve),当指定的 DOM 发生变化时,该实例会调用回调函数。构造函数接收两个参数:
- mutationRecord:用于存放所有 DOM 变化的数组。
- observer:观察者实例本身。
const createObserve = new MutationObserver((mutationRecoard,observe)=>{
})
MutationRecord 监听记录详情
每次 DOM 变化都会生成一条记录并存入 MutationRecord 数组中。该对象记录了每次变化的详细信息,具体结构如下:
| 属性 | 含义 |
|---|---|
| type | 观察的变动类型(attribute、characterData或者childList) |
| target | 发生变动的DOM节点 |
| addedNodes | 新增的DOM节点 |
| removedNodes | 删除的DOM节点 |
| previousSibling | 前一个同级节点,如果没有则返回null |
| nextSibling | 下一个同级节点,如果没有则返回null |
| attributeName | 发生变动的属性。如果设置了attributeFilter,则只返回预先指定的属性 |
| oldValue | 变动前的值。这个属性只对attribute和characterData变动有效,如果发生childList变动,则返回null |
具体结构如下图所示:

二、MutationObserver 实例对象方法
1. observe(node, config)
该方法用于配置 MutationObserver,使其在 DOM 更改匹配给定选项时,通过回调函数接收通知。它包含两个参数:
- node:需要观察的目标节点。
- config:配置对象,用于指定观测的具体变化类型。
配置项的详细属性如下:
| 属性 | 含义 |
|---|---|
| childList | 子节点的变动(指新增,删除或者更改) |
| attributes | 属性的变动 |
| characterData | 节点内容或节点文本的变动 |
| subtree | 布尔值,表示是否将该观察器应用于该节点的所有后代节点 |
| attributeOldValue | 布尔值,表示观察attributes变动时,是否需要记录变动前的属性值 |
| characterDataOldValue | 布尔值,表示观察characterData变动时,是否需要记录变动前的值 |
| attributeFilter | 数组,表示需要观察的特定属性(比如[‘class’,‘src’]) |
2. disconnect()
该方法用于阻止 MutationObserver 实例继续接收通知。调用后,直到再次调用 observe() 方法前,该观察者的回调函数将不再被触发。
3. takeRecords()
该方法从通知队列中移除所有待处理的记录,并将它们返回到一个新的 MutationRecord 对象数组中。
三、案例
- 创建一个观察器并传入回调函数。
- 为观察器配置观察节点。
- 指定观察特定配置的 DOM 变化。
- 执行观察器回调。
- 获取到 DOM 变化记录。
<div class="content">
<ui>
<li class="0">0000000</li>
<li class="1">1111111</li>
<li class="2">222222</li>
<li class="3">33333</li>
<li class="4">4444</li>
<li class="5">55555</li>
<li class="6">6666</li>
<li class="7">77777</li>
<li class="8">888888</li>
<li class="9">99999</li>
</ui>
</div>
// 观察器的配置(需要观察什么变动)
const config = { attributes: true, childList: true, subtree: true,characterData:true,characterDataOldValue:true,attributDataOldValue:true};
// 当观察到变动时执行的回调函数
const callback = function(mutationRecoard, observer) {
// Use traditional 'for loops' for IE 11
for(let mutation of mutationRecoard) {
if (mutation.type === 'childList') {
console.log('A child node has been added or removed.');
}
else if (mutation.type === 'attributes') {
console.log('The ' + mutation.attributeName + ' attribute was modified.');
}
}
};
// 创建一个观察器实例并传入回调函数
const observer = new MutationObserver(callback);
// 以上述配置开始观察目标节点
observer.observe(document.getElementsByClassName('content')[0], config);
// 之后,可停止观察
observer.disconnect();到此这篇关于 JavaScript MutationObserver 实例讲解的文章就介绍到这了,更多相关 JS MutationObserver 内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
js-cookie 安装与基础用法:set、get、remove 详解
2026-11-05 16:35:06
适合JavaScript初学者的实战项目:制作简易待办事项列表
2026-11-05 16:17:07
JS打开新标签页时怎么通过URL传递参数
2026-11-05 12:21:08
sigma.js 自定义节点样式:设置颜色、大小及标签显示的技巧
2026-11-05 09:55:00
JS 生成的统计图怎么导出为 PNG 图片或 PDF 文件?
2026-11-05 09:37:58
