基础篇:MutationObserver对象

MutationObserver 接口提供了监视对 DOM 树所做更改的能力,比如,节点的增减、属性的变动、文本内容的变动。它是 DOM3 Events 规范的一部分,用来替代旧的 Mutation Events 功能。

概念上,它很接近事件,可以理解为 DOM 发生变动就会触发 Mutation Observer 事件。但是,它与事件有一个本质不同:事件是同步触发,也就是说,DOM 的变动立刻会触发相应的事件;Mutation Observer 则是异步触发,DOM 的变动并不会马上触发,而是要等到当前所有 DOM 操作都结束才触发。

Mutation Observer 有以下特点:

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

构造函数

MutationObserver() 构造函数创建并返回一个新的观察器,它会在 DOM 变化时,调用指定的回调函数。MutationObserver 对 DOM 的观察不会立即启动;而必须先调用 observe() 方法来确定,要监听哪一部分的 DOM 以及要响应哪些更改。

const observer = new MutationObserver(callback);

callback 是一个回调函数,在指定的节点或子树以及配置项有 DOM 变动时会被调用。回调函数拥有两个参数:一个是描述所有被触发改动的 MutationRecord 对象数组,另一个是调用该函数的 MutationObserver 对象。

const observer = new MutationObserver(function callback (mutationList, mObserver) {
    mutationList.forEach((mutation) => {
        switch(mutation.type) {
            case 'childList':
                console.log('从树上添加或移除一个或更多的子节点')
                break;
            case 'attributes':
                console.log('节点的一个属性值被更改')
                break;
        }
    });
});
observer.observe(document.body, {
    childList: true,  // 观察目标子节点的变化,是否有添加或者删除
    attributes: true, // 观察属性变动
    subtree: true     // 观察后代节点,默认为 false
});

方法

observe()

配置了 MutationObserver 对象的回调方法以开始接收与给定选项匹配的 DOM 变化的通知。根据配置,观察者会观察 DOM 树中的单个 Node,也可能会观察被指定节点的部分或者所有的子孙节点。

要停止 MutationObserver(以便不再触发它的回调方法),需要调用 MutationObserver.disconnect() 方法。

mutationObserver.observe(target[, options])
  • target: DOM 树中的一个要观察变化的 DOM 节点(可能是一个 Element),或者是被观察的子节点树的根节点。

  • options(可选): 描述了 DOM 的哪些变化应该提供给当前观察者的回调函数。

    • childList(可选): 是否监视目标节点(如果 subtree 为 true,则包含子孙节点)添加或删除新的子节点,默认值为 false。
    • attributes(可选): 是否观察受监视元素的属性值变更,默认值 false。
    • characterData(可选): 是否监视指定目标节点或子节点树中节点所包含的字符数据的变化。无默认值。

    • attributeFilter(可选): 要监视的特定属性名称的数组,无默认值。如果未包含此属性,则对所有属性的更改都会触发变动通知。

    • attributeOldValue(可选): 当监视节点的属性改动时,将此属性设为 true 时,将记录任何有改动的属性的上一个值。无默认值。
    • characterDataOldValue(可选): 是否在文本在受监视节点上发生更改时记录节点文本的先前值。无默认值。
    • subtree(可选):是否监视范围扩展至目标节点整个节点树中的所有节点,默认值 false。其他值也会作用于此子树下的所有节点,而不仅仅只作用于目标节点。

以下任一情况都会抛出异常:

  • 配置选项使得实际上不会监视任何内容,即 childList、attributes、characterData 三个属性都为 false。
  • attributes 为 false,但是 attributeOldValue 为 true 或者 attributeFilter 配置存在。
  • characterData 为 false,但是 characterDataOldValue 为 true。

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

takeRecords()

返回已检测到但尚未由观察者的回调函数处理的所有匹配 DOM 更改的列表,使变更队列保持为空

此方法最常见的使用场景是在断开观察者之前,立即获取所有未处理的更改记录,以便在停止观察者时可以处理任何未处理的更改。

注意: 调用 takeRecords() 后,已发生但未传递给回调的变更队列将保留为空。

disconnect()

告诉观察者停止观察变动。 可以通过再次调用 observe() 方法来重启观察者。

注意: 所有已经检测到但是尚未向观察者报告的变动都会被丢弃。

注意: 如果被观察的元素被从 DOM 中移除,然后被浏览器的垃圾回收机制释放,此 MutationObserver 将同样被删除。

参考资料

MDN - MutationObserver

阮一峰 - Mutation Observer API

© lizhao all right reserved,powered by Gitbook文件修订时间: 2022-08-04 22:46:12

results matching ""

    No results matching ""