MutationObserver API 让我们能监听 DOM 树变化,该 API 设计用来替换掉在 DOM 3 事件规范中引入的 Mutation events。
Mutation events 是同步触发的,每次变动都会触发一次调用。 MutationObserver API 是异步触发的, DOM 的变动并不会马上触发,而是要等到当前所有 DOM 操作都结束才触发。所以 MutationObserver 相比 Mutation events 性能要更高。
Mutation Observer 有以下特点:
- 它等待所有脚本任务完成后,才会运行(即异步触发方式)。
- 它把 DOM 变动记录封装成一个数组进行处理,而不是一条条个别处理 DOM 变动。
- 它既可以观察 DOM 的所有类型变动,也可以指定只观察某一类变动。
// 某个需要被监控的 dom 元素。
var targetNode = document.getElementById('testId');
//配置 dom 的哪些改变会触发回调函数,详细见下文表格。
var config= { attributes: true, attributeFilter:['offsetTop'] };
// dom 变化时触发的回调函数,传入 mutationsList:记录 dom 变化的对象数组。
var callback = function(mutationsList) {
// Use traditional 'for loops' for IE 11
for (let mutation of mutationsList) {
if (mutation.type === "childList") {
console.log("A child node has been added or removed.");
} else if (mutation.type === "attributes" && mutation.attributeName === 'offsetTop') {
console.log("The " + mutation.offsetTop + " attribute was modified.");
}
}
};
// 创建一个 MutationObserver 示例,传入回调函数
var observer = new MutationObserver(callback);
// 注册监控的节点、监控的事件
observer.observe(targetNode, config);
// 停止监控
observer.disconnect();
mutationObserverInitConfig 配置对象如下:
- childList:Bolean,子节点的变动(指新增,删除或者更改)。
- attributes:Bolean,属性的变动。
- characterData:Bolean,节点内容或节点文本的变动。
- subtree:Bolean,表示是否将该观察器应用于该节点的所有后代节点。
- attributeOldValue:Bolean,表示观察attributes变动时,是否需要记录变动前的属性值。
- characterDataOldValue:Bolean,表示观察characterData变动时,是否需要记录变动前的值。
- attributeFilter:Array,表示需要观察的特定属性(比如[‘class’,‘src’,‘
offsetTop
’])。
应用场景:
检测DOM变化并做出响应
比如使用MutationObserver实现图片懒加载,监视img标签的visibilitychange事件,做出响应;或者当元素的偏移top在窗口内时做出加载图片操作
动态样式变化
监听style或者class的变化做出响应,比如我之前的应用:监听antd的模态窗变化,做出后续操作标签之间通信
通过监听data-key属性的变化发送、接收消息