如何在MutationObserver的回调中“暂停”观察

时间:2017-06-12 15:25:58

标签: javascript asynchronous recursion callback mutation-observers

例如,我想在.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);

1 个答案:

答案 0 :(得分:0)

使用全局变量似乎是正确的方法。但他们不需要全球化:

var svg = d3.select("body").append('svg').attr('width', 300).attr('height', 300),

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

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()}
};