李恒道 发表于 2021-9-15 23:41:57

[油猴脚本开发指南]MutationObserver的使用

tia# MutationObserver

[`MutationObserver`](https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver)接口提供了监视对DOM树所做更改的能力。它被设计为旧的Mutation Events功能的替代品,该功能是DOM3 Events规范的一部分。

具体可以参考https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver

那Mutation Events是什么呢?

# Mutation Events

可以参考https://developer.mozilla.org/en-US/docs/Web/API/MutationEvent

MutationEvents目前已经被弃用,不再推荐此功能。虽然一些浏览器可能仍然支持它,但它可能已经从相关的 Web 标准中删除,可能正在被删除,或者可能只是为了兼容性目的而保留。

```
Adding DOM mutation listeners to a document profoundly degrades the performance of further DOM modifications to that document (making them 1.5 - 7 times slower!). Moreover, removing the listeners does not reverse the damage.
```

添加Dom Muatation Listeners对document进行dom修改时会严重降低性能,大概导致缓慢1.5-7倍,并且,移除listener并不能逆转这种破坏!

以下为所有Mutation Events的列表

```javascript
DOMAttrModified
DOMAttributeNameChanged
DOMCharacterDataModified
DOMElementNameChanged
DOMNodeInserted
DOMNodeInsertedIntoDocument
DOMNodeRemoved
DOMNodeRemovedFromDocument
DOMSubtreeModified
```

通常使用进行注册Mutation Event(也就是之前我介绍的那种方式)

```javascript
element.addEventListener("DOMNodeInserted", function (event) {
// ...
}, false);
```

# 转变

所以这时候我们为了避免性能的减缓,就使用了MutationObserver,其使用方式也相对之前有所改变

## 构造函数

[`MutationObserver()`](https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver/MutationObserver "MutationObserver()")
创建并返回一个新的 `MutationObserver` 它会在指定的DOM发生变化时被调用。

## 使用方法

[`disconnect()`](https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver/disconnect "disconnect()")
阻止MutationObserver 实例继续接收的通知,直到再次调用其[`observe()`](https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver/observe "observe()")方法,该观察者对象包含的回调函数都不会再被调用。
[`observe()`](https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver/observe "observe()")
配置`MutationObserver`在DOM更改匹配给定选项时,通过其回调函数开始接收通知。
[`takeRecords()`](https://developer.mozilla.org/zh-CN/docs/Web/API/MutationObserver/takeRecords "takeRecords()")
从MutationObserver的通知队列中删除所有待处理的通知,并将它们返回到[`MutationRecord`](https://developer.mozilla.org/zh-CN/docs/Web/API/MutationRecord)对象的新[`Array`](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array)中。

# MutationObserver例子

选自博客https://hacks.mozilla.org/2012/05/dom-mutationobserver-reacting-to-dom-changes-without-killing-browser-performance/

```
const targetNode = document.getElementById('some-id');

// 观察器的配置(需要观察什么变动)
const config = { attributes: true, childList: true, subtree: true };

// 当观察到变动时执行的回调函数
const callback = function(mutationsList, observer) {
    // 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') {
            console.log('The ' + mutation.attributeName + ' attribute was modified.');
      }
    }
};

// 创建一个观察器实例并传入回调函数
const observer = new MutationObserver(callback);

// 以上述配置开始观察目标节点
observer.observe(targetNode, config);

// 之后,可停止观察
observer.disconnect();
```

# 补充

我大概查阅了一下资料,认为MutationObserve是为了解决性能问题而产生的api,但是除了MutationEvents的性能问题,其目的主要为了监控Dom的插入、修改、以及删除。注意,这并不代表addeventlitener的废除!由于api目前接触时间较短,可能对其有一定的错误理解,欢迎补充!撒花~

王一之 发表于 2021-9-16 09:32:26

ggnb!学习学习

Ne-21 发表于 2021-9-16 10:25:04


ggnb!学习学习

无了 发表于 2021-9-16 12:25:10

好,慢慢学
页: [1]
查看完整版本: [油猴脚本开发指南]MutationObserver的使用