zoukankan      html  css  js  c++  java
  • MutationObserver DOM变化的观察

    简单的给MutationObserver做个测试及总结笔记。

    MutationObserver,window上的一个(构造)函数,可以通过其创建的观察者(观察对象)达到观察DOM的变化的效果。

    可适用的需求:开发者在DOM变化过程中的debug、根据页面变化处理不同的资源、拦截网页是否被注入动态内容加载的脚本等等...

    简单的案例代码如下,比如观察属性变化:

    <button id="J_click">click</button>
    <div id="J_dom" data-num="1">hello</div>
    <script>
        var dom = document.getElementById('J_dom');
    
        var domObservable = new MutationObserver(function (mutationRecord) {
            console.log('mutationRecord : ', mutationRecord)
        });
    
        document.getElementById('J_click').addEventListener('click', domChange, !1);
        
        domObservable.observe(dom, {
            attributes: true,
            attributeOldValue: true
        })
    
        function domChange() {
            dom.setAttribute('data-num', +(dom.getAttribute('data-num')) + 1);
        }
    </script>

    点击"click"按钮,J_dom的data-num属性从0变为1。控制台输出如下MutationRecord对象列表:

    MutationObserver 构造函数需要传入一个回调函数用以执行观察到DOM变化后需要做的操作,回调函数以MutationRecord对象列表作为参数。

    MutationRecord对象列表

    MutationRecord对象包含以下属性:

    1. type,DOM变化的类型,DOM属性变化为"attributes";DOM内数据变化为"characterData";子节点树结构变化为"childList";

    2. target,如果如果type不为"childList",则代表发生变化的节点;如果type为"childList",则是被操作子节点(新增或删除)的父节点;

    3. addedNodes,被观察的DOM内新增的节点列表;

    4. removedNodes,被观察的DOM内移除的节点列表;

    5. previousSibling,被添加或移除节点之前的兄弟节点;

    6. nextSibling,被添加或移除节点之后的兄弟节点;

    7. attributeName,被修改属性的属性名;

    8. attributeNamespace,被修改属性的命名空间;

    9. oldValue,旧值,根据type而返回对应的旧属性或旧数据。

    观察者(观察对象)

    观察者对象上存在3个操作方法:observe、takeRecords、disconnect。

    observe方法指定一个被观察的DOM,配置该节点内的哪些变化需要被观察。方法使用如下: 

    var domObservable = new MutationObserver(function (mutationRecord) {
        // 变化后的处理代码
    });
    
    domObservable.observe(/* 被观察的DOM */, /* 配置参数 */{
        subtree: false,  // 观察范围是否包含子节点的变化,true则包括,false则不包括
        childList: false,  // 被观察的节点的子节点变化,true则观察,false则不观察
        attributes: false,  // 被观察的节点的属性变化,true则观察,false则不观察
        attributeOldValue: false,  // MutationRecord对象上是否返回被观察的节点的属性变化之前的旧值,true则返回,false则不返回
        attributeFilter: [/* 指定被观察的属性列表 */],  // attributes为true时生效,比如设置了列表为['class'],则只观察class的变化
        characterData: false,   // 被观察的节点的数据变化,true则观察,false则不观察
        characterDataOldValue: false  // MutationRecord对象上是否返回被观察的节点的数据变化之前的旧值,true则返回,false则不返回
    });
    /**
      * 注意:
      * 在attributes未被配置的情况下,如果attributeOldValue为true或者attributeFilter被设置,则attributes默认为true。
      * 在characterData未被配置的情况下,如果characterDataOldValue为true,则characterData默认为true。
      */

    takeRecords方法返回当前操作后的MutationRecord对象列表。方法使用如下:

    <button id="J_takeRecords">take records</button>
    <div id="J_dom" data-num="1">
        <span id="J_words">0</span>
        <div id="J_subDom"></div>
    </div>
    <script>
        var value = 0;
        var operateDom = document.getElementById('J_dom');
        var wordsDom = document.getElementById('J_words');
        var takeRecordsBtn = document.getElementById('J_takeRecords');
    
        takeRecordsBtn.addEventListener('click', takeRecords, !1);
    
        function takeRecords() {
            console.log('%c both change attribute and subtree', 'color:blue');
            operateDom.setAttribute('data-num', +(operateDom.getAttribute('data-num')) + 1);
            wordsDom.innerText = wordsDom.innerText === '0' ? '' : '0';
            var result = domObservable.takeRecords();
            console.log(result);
        }
    
        var domObservable = new MutationObserver(function (mutationsList) {
            console.log('mutationsList ', mutationsList);
        })
    
        domObservable.observe(operateDom, {
            subtree: true,
            attributes: true,
            attributeOldValue: true,
            characterData: true,
            characterDataOldValue: true
        });
    </script>
    <!-- 点击"take records"按钮,J_dom的data-num属性从0变为1,J_words里的0变成零 -->
    <!-- 分别为一次attrbutes和一次characterData变化,takeRecords方法被调用返回一个包含两次变化的MutationRecord对象列表。
    -->

    disconnect方法移除该观察者上的所有观察并清空该对象的MutationRecord对象列表。

    最后,MutationObserver的兼容性如下:

    嗯,还算行...

  • 相关阅读:
    OpenStack对象存储——Swift
    使用ssh对服务器进行登录
    在MacOs上配置Hadoop和Spark环境
    DOTA与面向对象的编程思想(3)——英雄的生命周期
    DOTA与面向对象的编程思想(2)——三层架构,让游戏跑起来
    DOTA与面向对象编程思想(1)——分述DOTA和面向对象思想
    再谈面向对象
    linux C 列出目录中的文件列表 包含文件的相关信息
    在Ubuntu 64位下搭建samba,实现linux与windows之间的资源共享,配置实现Ubuntu启动后samba服务与ssh服务开机自动启动
    LINUX下使用elasticsearch-jdbc工具实现MySQL同步到ElasticSearch 以及linux 64位centos系统安装jdk1.8
  • 原文地址:https://www.cnblogs.com/ys-ys/p/10091137.html
Copyright © 2011-2022 走看看