MutationObserver用来监视 DOM 变动。DOM 的任何变动,比如节点的增减、属性的变动、文本内容的变动都会触发MutationObserver事件。
但是,它与事件有一个本质不同:事件是同步触发,也就是说,DOM 的变动立刻会触发相应的事件;Mutation Observer 则是异步触发,DOM 的变动并不会马上触发,而是要等到当前所有 DOM 操作都结束才触发。
Mutation Observer 有以下特点:

  • 它等待所有脚本任务完成后,才会运行(即异步触发方式)。
  • 它把 DOM 变动记录封装成一个数组进行处理,而不是一条条个别处理 DOM 变动。
  • 它既可以观察 DOM 的所有类型变动,也可以指定只观察某一类变动。

MutationObserver 构造函数

var observer = new MutationObserver(function (mutationRecoards, observer) {
	// mutationRecoards变动数组
	// observer 观察者实例
});

构造函数接收一个回调函数,回调函数有两个参数,一个变动数组,第二个是观察者实例。

MutationObserver 的实例方法

1. observe(node, config)

启动监听,它接受两个参数。
第一个参数:所要观察的 DOM 节点
第二个参数:一个配置对象,指定所要观察的特定变动
配置对象如下:

  • childList:子节点的变动(指新增,删除或者更改)。
  • attributes:属性的变动。
  • characterData:节点内容或节点文本的变动。
  • subtree:布尔值,表示是否将该观察器应用于该节点的所有后代节点。
  • attributeOldValue:布尔值,表示观察attributes变动时,是否需要记录变动前的属性值。
  • characterDataOldValue:布尔值,表示观察characterData变动时,是否需要记录变动前的值。
  • attributeFilter:数组,表示需要观察的特定属性(比如[‘class’,‘src’])。
// 开始监听文档根节点(即<html>标签)的变动
mutationObserver.observe(document.documentElement, {
  attributes: true,
  characterData: true,
  childList: true,
  subtree: true,
  attributeOldValue: true,
  characterDataOldValue: true
});

对一个节点添加观察器,就像使用addEventListener方法一样,多次添加同一个观察器是无效的,回调函数依然只会触发一次。但是,如果指定不同的options对象,就会被当作两个不同的观察器。

2. disconnect()

disconnect方法用来停止观察。调用该方法后,DOM 再发生变动,也不会触发观察器。

3. takeRecords()

用来清除变动记录,即不再处理未处理的变动。该方法返回变动记录的数组。

MutationRecord 对象

DOM 每次发生变化,就会生成一条变动记录(MutationRecord 实例)。该实例包含了与变动相关的所有信息。Mutation Observer 处理的就是一个个MutationRecord实例所组成的数组。
MutationRecord对象包含了DOM的相关信息,有如下属性:

  • type:观察的变动类型(attribute、characterData或者childList)。
  • target:发生变动的DOM节点。
  • addedNodes:新增的DOM节点。
  • removedNodes:删除的DOM节点。
  • previousSibling:前一个同级节点,如果没有则返回null。
  • nextSibling:下一个同级节点,如果没有则返回null。
  • attributeName:发生变动的属性。如果设置了attributeFilter,则只返回预先指定的属性。
  • oldValue:变动前的值。这个属性只对attribute和characterData变动有效,如果发生childList变动,则返回null。

例子

<div id="container">
        <div class="child"></div>
    </div>
    <button id="update">
        改变
    </button>
    <script>
        var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver
        const container = document.getElementById('container')
        const button = document.getElementById('update')
        const options = {
            attributes: true,
            childList: true,
        }
        // 创建MutationObserver实例,返回一个观察者对象
        const mutation = new MutationObserver(function(mutationRecoards, observer) {
            console.log(mutationRecoards)
            console.log(observer)
        })
        // 对观察者添加需要观察的元素,并设置需要观察元素的哪些方面
        mutation.observe(container, options);

        // 对container进行操作
        button.addEventListener('click', function() {
            container.innerText = '这是文本';  // 内容改变
            container.style.background = 'red'; // 属性改变
            for (let i = 0; i < 3; i++) {  // 子节点
                container.appendChild(document.createElement('div'))
            }
        })
    </script>

在这里插入图片描述

参考

Mutation Observer API

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐