JavaScript MutationObserver 实例讲解

作者:像素猫时间:2026-10-27 00:08:06浏览:509

本文详细解析 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 内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!

作者最新文章