MutationObserver

吐槽君 分类:javascript

兼容性

image.png

概述

MutationObserver接口提供了监视对DOM树所做更改的能力。它被设计为旧的Mutation Events功能的替代品,该功能是DOM3 Events规范的一部分

MutationObserver 与 Mutation Events的对应关系

MutationEvent MutationObserver options
DOMNodeInserted { childList: true, subtree: true }
DOMNodeRemoved { childList: true, subtree: true }
DOMSubtreeModified { childList: true, subtree: true }
DOMAttrModified { attributes: true, subtree: true }
DOMCharacterDataModified { characterData: true, subtree: true }

MutationObserver对象有三个方法,分别如下

  1. observe:设置观察目标,接受两个参数
    • target:观察目标
    • options:通过对象成员来设置观察选项
  2. disconnect:阻止观察者观察任何改变
  3. takeRecords:清空记录队列并返回里面的内容

关于observe方法中options参数有已下几个选项:

  1. childList:设置true,表示观察目标子节点的变化,比如添加或者删除目标子节点,不包括修改子节点以及子节点后代的变化

  2. attributes:设置true,表示观察目标属性的改变

  3. characterData:设置true,表示观察目标数据的改变

  4. subtree:设置为true,目标以及目标的后代改变都会观察

  5. attributeOldValue:如果属性为true或者省略,则相当于设置为true,表示需要记录改变前的目标属性值,设置了attributeOldValue可以省略attributes设置

  6. characterDataOldValue:如果characterData为true或省略,则相当于设置为true,表示需要记录改变之前的目标数据,设置了characterDataOldValue可以省略characterData设置

  7. attributeFilter:如果不是所有的属性改变都需要被观察,并且attributes设置为true或者被忽略,那么设置一个需要观察的属性本地名称(不需要命名空间)的列表

    从上表我们也可以看出相比与MutationEvent而言MutationObserver极大地增加了灵活性,可以设置各种各样的选项来满足对目标的观察。

使用实例

// targetNode目标节点
addBg(targetNode, url) {
    const bgimg = `url(${url})`;
    // 配置观察选项
    const config = {
        attributes: true,
        childList: false,
        subtree: false
    };
    targetNode.style.backgroundImage = bgimg;
    let callback = function (mutationsList) {
        for (let mutation of mutationsList) {
            if (mutation.type === 'attributes' && mutation.attributeName === 'style') {
                targetNode.style.backgroundImage = bgimg;
            }
        }
    };
    // 创建观察者对象
    this.observer = new MutationObserver(callback);
    // 传入目标节点和观察项
    this.observer.observe(targetNode, config);
},
 

遇到的问题

背景:火狐浏览器下使用的时候遇到浏览器卡死的情况

原因:observe中的options的childlist, subtree属性为true导致监听的节点太多导致的

解决方案childlist, subtree属性设置为false,具体案例中只是为了让背景图一直存在,所以只需要监听attributes就可以了

回复

我来回复
  • 暂无回复内容