MutationObserver 给开发者们提供了一种能在某个范围内的 DOM 树发生变化时作出适当反应的能力。该 API 设计用来替换掉在 DOM 3 事件规范中引入的 Mutation 事件。
——MDN
1. 概述
-
监视 DOM 变动的接口
当监视的 DOM 发生变动时 MutationObserver 将收到通知并触发事先设定好的回调函数。
-
类似于事件,但是异步触发
添加监视时,MutationObserver 上的 observer 函数与 addEventListener 有相似之处,但不同于后者的同步触发,MutationObserver 是异步触发,此举是为了避免 DOM 频繁变动导致回调函数被频繁调用,造成浏览器卡顿。
2. MutationObserver 构造函数
该构造函数用于实例化一个新的 MutaionObserver ,同时指定触发 DOM 变动时的回调函数:
JavaScriptvar observer = new MutationObserver(callback);
callback,即回调函数接收两个参数,第一个参数是一个包含了所有 MutationRecord
对象(后文会介绍,别急)的数组,第二个参数则是这个MutationObserver 实例本身。
3. MutationObserver 实例方法
3.1 Observe(Node target, optional MutationObserverInit options);
给 MutationObserver 实例添加要观察的 DOM 节点,并可通过一个可选的 options 参数来配置观察哪些变动,该 options 为一个名为 MutationObserverInit
的对象。
以下是 MutationObserverInit
对象的各属性及其描述:
属性 | 类型 | 描述 |
---|---|---|
childList | Boolean | 是否观察子节点的变动 |
attributes | Boolean | 是否观察属性的变动 |
characterData | Boolean | 是否节点内容或节点文本的变动 |
subtree | Boolean | 是否观察所有后代节点的变动 |
attributeOldValue | Boolean | 观察 attributes 变动时,是否记录变动前的属性值 |
characterDataOldValue | Boolean | 观察 characterData 变动时,是否记录变动前的属性值 |
attributeFilter | Array | 表示需要观察的特定属性(比如['class','src']),不在此数组中的属性变化时将被忽略 |
注:
- 不能单独观察 subtree 变动,必须同时指定 childList、attributes 和 characterData 中的一种或多种。
- 为同一个 DOM 节点多次添加同一个 MutationObserver 是无效的,回调函数将只被触发一次。但如果指定不同的 options 对象(即观察不同的变动),即被视为不同的 MutationObserver。(是不是感觉跟 addEventListener 确实很像?)
3.2 disconnect();
该方法用来停止观察。后续如果 DOM 节点发生变动将不再触发回调函数。
JavaScriptobserver.disconnect();
继续类比,disconnect
函数和 removeEventListener
大致类似,除了 disconnect
函数比较粗暴(无法传参配置),会把该 MutationObserver 实例上所有的观察都停止。
3.3 takeRecords();
该方法用来清除变动记录,返回一个包含了 MutationRecord
对象的数组。MutationRecord
又出现了。它是啥?
实际上,DOM 每次发生变化,就会生成一条变动记录,这个变动记录对应一个 MutationRecord
对象。以下是 MutationRecord
对象的各属性及其描述:
属性 | 类型 | 描述 |
---|---|---|
type | String | 根据变动类型,值为 attributes, characterData 或 childList |
target | Node | 发生变动的DOM节点 |
addedNodes | NodeList | 被添加的节点,或者为 null |
removedNodes | NodeList | 被删除的节点,或者为 null |
previousSibling | Node | 被添加或被删除的节点的前一个兄弟节点,或者为 null |
nextSibling | Node | 被添加或被删除的节点的后一个兄弟节点,或者为 null |
attributeName | String | 发生变更的属性的本地名称,或者为 null |
attributeNamespace | String | 发生变更的属性的命名空间,或者为 null |
oldValue | String | 如果 type 为 attributes,则返回该属性变化之前的属性值;如果 type 为 characterData,则返回该节点变化之前的文本数据;如果 type为 childList,则返回 null |
前面我们说 MutationObserver 异步处理触发,实际上它的原理就是等待一个脚本任务完成,将这个过程中产生的所有变动记录即所有的 MutationRecord
对象存储到一个数组中,最后再统一处理这个数组。而这个包含了所有变动记录的数组,也将成为回调函数的第一个参数。下面是一个回调函数处理该数组的示例:
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
console.log(mutation.type);
});
});
4. 兼容性
MutationObserver 在 DOM Level 4 中被引入,其兼容性如下图所示:
DOM JavaScript 赏参考文献:
坚持原创技术分享,您的支持将鼓励我继续创作!

扫描二维码,分享此文章