DOM监控 MutationObserver

大家好!我是木瓜太香,一个传播webstorm使用技巧的前端工程师,这一次给大家带来的是 DOM 监控的方法。

MutationObserver 接口提供了监视DOM树更改的能力,是旧的 Mutation 的替代品

使用方式:通过 MutationObserver构造函数创建对象 ob,该对象下有以下可用方法

  • observe(dom对象,option) :配置MutationObserver在DOM更改匹配给定选项时,通过其回调函数开始接受通知
  • disconnect():取消监控
  • takeRecords():从MutationObserver的通知队列中删除所有待处理的通知,并将它们返回到 MutationRecord对象的新Array

一个简单的示例

html部分

<div class="container">
    <h1 class="title">一个标题</h1>
    <button class="btn">点击按钮取消监控</button>
</div>

javascript部分

,    let container = document.querySelector('.container');
    let btn = document.querySelector('.btn')

    btn.onclick = function (){
        console.log('监控已经取消');
        observer.disconnect();
    }

    function callback (){
        console.log("回调函数参数");
        console.log(arguments);
    }
    
    let observer = new MutationObserver(callback);

    observer.observe(container,{
        attributes: true // 指定元素属性改变的时候触发回调
    })

详解 observe disconnect takeRecords

  • observe 方法主要指定要监控哪些 DOM 的变化作为第一个参数传入,和要监控哪些地方,使用一个对象描述并作为第二个参数传入

    • 参数一: 要观察的 DOM 或者要观察的所有子节点的公共根节点

      • 参数二:一个可选的 MutationObserverInit对象,此对象的配置项描述了 DOM 的哪些变化要被监控,注意:childListattributes 或者 characterData 三个属性之中,至少有一个必须为 true,否则会抛出 TypeError 异常,实际有attributeFilter也行
    • MutationObserverInit 对象属性

      属性描述
      attributeFilter要监视的特定属性名称的数组。如果未包含此属性,则对所有属性的更改都会触发变动通知。无默认值。
      attributeOldValue当监视节点的属性改动时,将此属性设为 true 将记录任何有改动的属性的上一个值。有关观察属性更改和值记录的详细信息,详见Monitoring attribute values in MutationObserver。无默认值。
      attributes设为 true 以观察受监视元素的属性值变更。默认值为 false
      characterData设为 true 以监视指定目标节点或子节点树中节点所包含的字符数据的变化。无默认值。在监控该类值的时候,传入observe的第一个参数应该是 textNode 而非 element ,不然就需要配合 subtree 使用
      characterDataOldValue设为 true 以在文本在受监视节点上发生更改时记录节点文本的先前值。详情及例子,请查看 Monitoring text content changes in MutationObserver。无默认值。
      childList设为 true 以监视目标节点(如果 subtreetrue,则包含子孙节点)添加或删除新的子节点。默认值为 false
      subtree设为 true 以将监视范围扩展至目标节点整个节点树中的所有节点。MutationObserverInit 的其他值也会作用于此子树下的所有节点,而不仅仅只作用于目标节点。默认值为 false
    • 重复的 observe 调用后面会覆盖前面,前提是第一个参数是相同的,实质上只覆盖了要监控的类型也就是第二个参数
  • disconnect 方法移除监控,如果某个元素从 dom 树中移除那么 MutationObserve 将同样被删除
  • takeRecords 方法返回已检测到但尚未由观察者的回调函数处理的所有匹配DOM更改的列表,使变更队列保持为空。 此方法最常见的使用场景是在断开观察者之前立即获取所有未处理的更改记录,以便在停止观察者时可以处理任何未处理的更改。该方法通常是程序级别的监控,例如设置监控之后立马修改然后调用该方法就可以获取到信息

        let observer = new MutationObserver(callback);
        
        // console.log(container.childNodes);
    
    
        observer.observe(container.childNodes[0], {
            // attributes: true,
            characterData: true,
            characterDataOldValue: true,
            // childList: true,
            // subtree: true
            // attributeFilter: ["class","data-username"],
            // attributeOldValue: true
        })
    
        container.childNodes[0].textContent = "哈哈哈123"
        console.log(observer.takeRecords());

监控到变化之后获取信息:

只监控变化没有用,重要的是我们要知道哪里变了,通常我们可以拿到变化前的老值,新值可以通过具体dom对象获取,关于信息回调函数参数中的 MutationRecord 对象很重要

属性描述
MutationRecord.type如果是属性变化,则返回 "attributes";<br/>如果是 characterData 节点变化,则返回 "characterData";<br/>如果是子节点树 childList 变化,则返回 "childList"
MutationRecord.target根据 MutationRecord.type,返回变化所影响的节点。<br/>对于属性 attributes 变化,返回属性变化的节点。<br/>对于 characterData 变化,返回 characterData 节点。<br/>对于子节点树 childList 变化,返回子节点变化的节点。
MutationRecord.addedNodes返回被添加的节点。<br/>如果没有节点被添加,则该属性将是一个空的 NodeList
MutationRecord.removedNodes返回被移除的节点。<br/>如果没有节点被移除,则该属性将是一个空的 NodeList
MutationRecord.previousSibling返回被添加或移除的节点之前的兄弟节点,或者 null
MutationRecord.nextSibling返回被添加或移除的节点之后的兄弟节点,或者 null
MutationRecord.attributeName返回被修改的属性的属性名,或者 null
MutationRecord.attributeNamespace返回被修改属性的命名空间,或者 null
MutationRecord.oldValue返回值取决于 MutationRecord.type。 对于属性 attributes 变化,返回变化之前的属性值。 对于 characterData 变化,返回变化之前的数据。 对于子节点树 childList 变化,返回 null
注意,如果要让这个属性起作用,在相应的 MutationObserverInit 参数的 MutationObserver observe 方法中,attributeOldValue 或者 characterDataOldValue 必须设置为 true

特别注意:所有被监控到的更改,其记录的 target 信息都是具体被更改的那个节点对象,如果被更改的是 文本 那么 target 就是一个文本节点。

我有建立qun来让大家讨论前端相关问题,237871108
哔哩哔哩也可以搜索木瓜太香找到我。


木瓜太香
4 声望0 粉丝