是什么可能导致整个文档上的突变观察者,而子树则在孩子添加时不发射?
有时,突变观察者回调不会在我期望的时候发射。
如果我在开发人员工具控制台中运行此代码:
// 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控制台中的代码时,它可以正常工作:我看到突变:[mutationRecord]
已记录到控制台。
当我继续 Twitter 并在DevTools控制台中运行上述代码,它似乎不起作用:<代码突变:[突变记录]
未记录到控制台。
是什么可能导致突变观察者在Twitter上不起作用?
要重新创建问题,
- 请访问 twitter
- 打开DevTools console
- 粘贴以上代码,并参见
突变:[mutationRecord] /code>不记录
更新2
Now it works for me on twitter so seems intermittent.更新2
It's stopped working again on twitter. I also found if I add a mutation observer to a div I create, that also doesn't work but works on other sites.const newDiv = document.createElement('div')
newDiv.setAttribute('id','newDiv')
// 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(newDiv, {
childList: true,
subtree:true
});
// create new child
newDiv.appendChild(document.createElement("div"));
更新3
- 突变观察者尚未停止在隐身方面工作,而
- 在不工作时,请关闭所有扩展名 nove 均未解决突变观察者,
- 并且重新启动Chrome似乎 修复突变观察者停止工作时,
- 清除cookie 修复了问题
更新4个
It may be related to an infinite loop where when a mutation is observed, a node is added. This causes a mutation to be observed (the new added node). And so on...示例,
const callbackForAllChanges = function (mutationsList, observer) {
if (mutationsList.find((record) => record.type === "childList")) {
document.body.appendChild(document.createElement("div"));
}
};
我认为如果发生这种情况,它可能会触发突变工作以停止工作。
Sometimes the mutation observer callback doesn't fire when I expect it to.
If I run this code in developer tools console:
// 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"));
I would expect callback to fire when I create a new child. But sometimes it does and sometimes it doesn't.
When I run the code in the devtools console while on stackoverflow it works: I see mutations: [MutationRecord]
logged to the console.
When I go on twitter and run the above code in the devtools console, it doesn't seem to work: mutations: [MutationRecord]
is not logged to the console.
What could cause Mutation Observer to not work on twitter?
To recreate issue
- Go to twitter
- Open the devtools console
- Paste the above code and see
mutations: [MutationRecord]
does not log
UPDATE
Now it works for me on twitter so seems intermittent.
UPDATE 2
It's stopped working again on twitter. I also found if I add a mutation observer to a div I create, that also doesn't work but works on other sites.
const newDiv = document.createElement('div')
newDiv.setAttribute('id','newDiv')
// 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(newDiv, {
childList: true,
subtree:true
});
// create new child
newDiv.appendChild(document.createElement("div"));
UPDATE 3
- Mutation observer hasn't stopped working in incognito
- Turning all extension off doesn't fix mutation observer when it's not working
- Quitting and restarting chrome seems to fix Mutation observer when it stops working
- Clearing cookies does not fix the issue
UPDATE 4
It may be related to an infinite loop where when a mutation is observed, a node is added. This causes a mutation to be observed (the new added node). And so on...
Example
const callbackForAllChanges = function (mutationsList, observer) {
if (mutationsList.find((record) => record.type === "childList")) {
document.body.appendChild(document.createElement("div"));
}
};
I think if this happens it might trigger the mutation work to stop working.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我面临同样的问题,现在我通过使用循环并检查是否手动进行了一些更改来修补回调。
I am facing the same problem, for now I patched the callback by using a loop and checking if some changes were made manually.
我能够在以下特定情况下重现此操作:
其他轶事:
takeRecord()
按预期工作。如上,它充满了突变记录。QueuemicRotask(&lt; cb&gt;)
将您的工作与突变观察者回调中的工作解矛并不能解决问题。settimout(&lt; cb&gt; 0)
确实解决了问题。因此,如果您遇到与我相同的问题,解决方法是将您的突变观察者回调在
settimeout()
中,如下所示...我不愿意将其称为答案说实话。我相信这里有一个铬的heis虫。如果您从未打开开发工具,那么这种解决方法是多余的。
I'm able to reproduce this with these specific circumstances:
Other anecdotes:
takeRecord()
works as expected. As in, it was full of mutation records.queueMicrotask(<cb>)
to decouple your work from the mutation observer callback does NOT resolve the issue.setTimout(<cb>, 0)
DOES resolve the issue.So if you're experience the same issue that I am, the workaround will be to wrap your mutation observer callback in a
setTimeout()
as follows...I don't feel comfortable calling this an answer to be honest. I believe there is a heisen-bug in Chromium here. If you never open Dev Tools this workaround is superfluous.
此答案在
我想避免重构很多代码,因此我想出了这个hacky的解决方案,以将本机MutationObserver类包装在您自己的匿名类中(需要在之前运行任何被实例化的观察者):
This answer dovetails on the response from mayfield which is excellent. I agree that this is a Chromium Devtools bug, reproducible with the steps that he mentioned in his answer. setTimeout() seems to work (albeit inconsistently) to mitigate this. I wonder if this bug might also impact other observers as well ...
I wanted to avoid refactoring a lot of code so I came up with this hacky solution to wrap the native MutationObserver class in your own anonymous class (needs to be run prior to any observers being instantiated):