有时候,变异观察者回调函数并没有像我期望的那样被触发。
如果我在开发人员工具控制台中运行以下代码:
// callback for mutations observer
callbackForAllChanges = function (mutationsList, observer) {
console.log("mutations: ", mutationsList);
};
// create mutation observer
allChanges = new MutationObserver(callbackForAllChanges);
// attach mutation observer to document
allChanges.observe(document, {
childList: true,
subtree:true
});
// create new child
document.body.appendChild(document.createElement("div"));
当我创建一个新的子函数时,我希望回调函数能被触发,但有时它会被触发,有时不会。
当我在stackoverflow上运行devtools控制台中的代码时,它可以工作:我看到mutations: [MutationRecord]
已登录到控制台。
当我在twitter上运行上面的代码时,在devtools控制台中,它似乎不起作用:mutations: [MutationRecord]
未记录到控制台。
什么原因会导致Mutation Observer无法在Twitter上运行?
重新创建问题
1.转到twitter
1.打开devtools控制台
1.粘贴上面的代码并查看mutations: [MutationRecord]
does not log
更新
现在它在twitter上对我有效,所以看起来断断续续。
更新2
它在twitter上又停止工作了。我还发现,如果我向我创建的div添加一个突变观察器,它也不起作用,但在其他网站上起作用。
更新3
- 变异观察者一直在隐姓埋名
- 关闭所有扩展 * 不会修复 * 突变观察器不工作时的问题
- 退出并重新启动chrome似乎可以修复当它停止工作时的突变观察器
- 清除cookie * 并不能 * 解决问题
更新4
它可能与一个无限循环有关,当观察到一个突变时,会添加一个节点。这会导致观察到一个突变(新添加的节点)。依此类推......
示例
const callbackForAllChanges = function (mutationsList, observer) {
if (mutationsList.find((record) => record.type === "childList")) {
document.body.appendChild(document.createElement("div"));
}
};
我认为如果发生这种情况,它可能会触发突变工作停止工作。
3条答案
按热度按时间voj3qocg1#
我也面临着同样的问题,现在我使用一个循环来修补回调,并检查是否手动进行了一些更改。
gcuhipw92#
我可以在这些特定的情况下重现这个:
1.开发工具已打开
1.代码在MutationObserver回调中具有断点或调试器语句
1.第一次加载页,并且页在断点处成功停止
1.当仍在断点中时重新加载页面
1.关闭网页和任何其他网站,并启动一个新的标签(即创建新的网页进程)重置状态回到第一步
其他轶事:
takeRecord()
可以正常工作。queueMicrotask(<cb>)
将您的工作与突变观察器回调解耦并不能解决这个问题。setTimout(<cb>, 0)
可以解决问题。因此,如果您遇到了与我相同的问题,解决方法是将您的mutation observer回调 Package 在
setTimeout()
中,如下所示......老实说,我不太愿意把这个叫做答案。我相信Chromium中有一个海森bug。如果你从来没有打开过开发工具,这个解决方案是多余的。
ilmyapht3#
这个答案与response from mayfield非常吻合。我同意这是一个Chromium Devtools的bug,可以通过他在回答中提到的步骤重现。setTimeout()似乎可以缓解这个问题(尽管不一致)。我想知道这个bug是否也会影响其他观察者...
我想避免重构大量代码,所以我想出了这个黑客解决方案,将本地MutationObserver类 Package 在自己的匿名类中(需要在示例化任何观察者之前运行):