如何在 MutationObserver 的回调中“暂停”观察
Posted
技术标签:
【中文标题】如何在 MutationObserver 的回调中“暂停”观察【英文标题】:How to "Pause" observing in callback of a 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);
【问题讨论】:
【参考方案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.js
的setMutationHandler
。我没有找到访问原始目标和配置的方法。不修改原来的setMutationHandler.js
可以reconnect
吗?以上是关于如何在 MutationObserver 的回调中“暂停”观察的主要内容,如果未能解决你的问题,请参考以下文章
30天精通JavaScript第24天 DOM规范中的MutationObserver接口