【问题标题】:How to "Pause" observing in callback of a MutationObserver如何在 MutationObserver 的回调中“暂停”观察
【发布时间】:2017-11-14 03:36:30
【问题描述】:

比如我想在.my-codes写一些代码。

<head>
<script class="my-codes">
    var ob = new MutationObserver(
        function (mutations) {
            mutations.forEach(
                mutation => {
                    mutation.addedNodes.forEach(
                        node => {
                            if(node.nodeName === "DIV"){
                                // Without this browser may crush for infinite recursion
                                this.disconnect(); 
                                let innerNode = document.createElement("div");
                                innerNode.className = "inner-div";
                                console.log("Insert div to a ." + node.className);
                                node.appendChild(innerNode);
                                // Method below does not exist
                                /* this.reconnect(); */ 
                            }
                        }
                    )
                }
            );
        }
    );
    ob.observe(document, {childList:true, subtree:true});
</script>
</head>
<body>
    <div class="div1">
        <script>
            let asyncDiv = document.createElement("div");
            asyncDiv.className = "div3";
            setTimeout(()=>document.body.appendChild(asyncDiv), 10);
        </script>
    </div>
    <div class="div2"></div>
</body>

预期结果(如果存在 this.reconnect(); 之类的东西):

<div class="div1">
    <div class="inner-div"></div>
</div>
<div class="div2">
    <div class="inner-div"></div>
</div>
<div class="div3">
    <div class="inner-div"></div>
</div>

实际结果(第一次插入后观察完全停止):

<div class="div1">
    <div class="inner-div"></div>
</div>
<div class="div2"></div>
<div class="div3"></div>

有没有可靠的方法来实现this.reconnect();函数?

(最好不要乱用全局变量,下面的代码不认为是可靠的方法,因为回调函数需要捕获全局变量)

var target = document;
var config = {childList:true, subtree:true};
var ob = new MutationObserver(
    function(mut, observer){
        this.disconnect();
        /* mess with DOM */
        observer.observe(target, config);
    }
)
ob.observe(target, config);

【问题讨论】:

    标签: javascript asynchronous recursion callback mutation-observers


    【解决方案1】:

    这似乎是使用某种全局变量的正确方法。但它们不需要是全球性的:

    function observe(target,config){
      target =target|| document;
      config = config||{childList:true, subtree:true};
      var ob = new MutationObserver(function(mut, observer){
          ob.disconnect();
        /* mess with DOM */
          ob.observe(target, config);
      });
     ob.observe(target, config);
    }
    
    observe();
    

    这可以扩展以提供更通用的观察方式:

    function customObserver(target,config,callback){
     this.target =target|| document;
     this.config = config||{childList:true, subtree:true};
     var that=this;
     this.ob = new MutationObserver(function(mut,observer){
        callback.call(that,mut,observer);
     });
     }
    
    customObserver.prototype={
      connect:function(){
        this.ob.observe(this.target,this.config);
      },
     disconnect:function(){ this.ob.disconnect()}
    };
    

    所以可以这样做:

    var observer=new customObserver(document,false,function(observer,mutations){
      observer.disconnect();
      //som DOM changes
     observer.connect();
    });
    observer.connect();
    

    【讨论】:

    • 事实上我是尝试reconnect的人,我正在使用来自https://greasyfork.org/scripts/12228/code/setMutationHandler.jssetMutationHandler。我没有找到访问原始目标和配置的方法。不修改原来的setMutationHandler.js可以reconnect吗?
    猜你喜欢
    • 2013-07-25
    • 1970-01-01
    • 2016-02-14
    • 1970-01-01
    • 2020-09-25
    • 2020-06-05
    • 2017-12-20
    • 2018-07-04
    • 1970-01-01
    相关资源
    最近更新 更多