gpt4 book ai didi

javascript - 删除元素后的 MutationObserver 行为

转载 作者:数据小太阳 更新时间:2023-10-29 06:01:07 25 4
gpt4 key购买 nike

我有一个 MutationObserver 绑定(bind)到 #foo html 元素。

var target = document.querySelector("#foo");
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
// ...
});
});

当用户点击 #button 元素时,#foo 会被移除并在一秒钟后再次出现。

<div id="button">Click me to remove the Foo!</div>
<div id="foo">Hello, I'm Foo!</div>

正如我所注意到的,在删除并重新创建 #foo 后,观察器停止工作。

  • 这是正常行为吗?
  • 那么,我需要再次启动观察器吗?

第三个问题:

  • 第一个观察者是否被完全移除?或者,相反,它仍在运行,只是“什么都不做”? - 我问这个问题,因为我不希望多个观察者运行,如果只有一个观察者在做真正的工作的话。

最佳答案

and appears again after a second

行为将完全取决于您的意思。

如果你的意思是创建一个具有相同 idnew 元素,那么是的,这是预期的行为:当你调用 observer.observe 在元素上,您是在那个特定元素 上调用它,而不是在任何与其 ID 匹配的元素上调用它。如果您从 DOM 中删除该元素并将其替换为另一个看起来相同的不同元素,则观察者不会神奇地连接到该新的不同元素:

var target = document.querySelector("#foo");
var observer = new MutationObserver(function(mutations) {
console.log("#foo was modified");
});
observer.observe(target, {subTree: true, childList: true});
var counter = 0;
tick();
setTimeout(function() {
console.log("Replacing foo with a new one");
target.parentNode.removeChild(target);
target = document.createElement("div");
target.id = "foo";
target.innerHTML = "This is the new foo";
document.body.insertBefore(target, document.body.firstChild);
}, 1000);
function tick() {
target.appendChild(document.createTextNode("."));
if (++counter < 20) {
setTimeout(tick, 200);
}
}
<div id="foo">This is the original foo</div>

如果您的意思是将相同的元素放回到 DOM 中,那么不,这不是预期的行为,也不是本例中发生的情况:

var target = document.querySelector("#foo");
var observer = new MutationObserver(function(mutations) {
console.log("#foo was modified");
});
observer.observe(target, {subTree: true, childList: true});
var counter = 0;
tick();
setTimeout(function() {
console.log("Removing foo for a moment");
target.parentNode.removeChild(target);
setTimeout(function() {
console.log("Putting the same foo back in");
document.body.insertBefore(target, document.body.firstChild);
}, 100);
}, 1000);
function tick() {
target.appendChild(document.createTextNode("."));
if (++counter < 20) {
setTimeout(tick, 200);
}
}
<div id="foo">This is the original foo</div>

此处的关键信息是观察者正在观察您传递给 observe一个特定元素


这些问题仅在您删除旧元素并将其替换为全新元素时适用:

So, I need to launch the observer again?

如果您要删除原始元素并放置一个新元素,您应该告诉观察者停止观察:

observer.disconnect();

一旦有了新元素,就可以将观察者连接到它:

observer.observe(theNewElement, /*...options go here...*/);

Is the first observer is totally removed? Or, instead of that, it is still running, with just "doing nothing"?

理论上,因为the spec清楚地表明它是引用其观察者的元素,然后如果您释放对该元素的唯一引用,理论上观察者会断开连接,因为该元素及其观察者列表已被清理。但是,尚不清楚观察者的 disconnect 方法如何在观察者没有返回元素的引用的情况下实现,因此它们可能具有相互引用。如果您保留对观察者的引用,那将在内存中保留相互引用。可以肯定的是,我会故意断开它。

I'm asking about it, because I don't want the multiple observers run, if only one of them doing the real work.

观察者不“跑”,他们 react 。观察者将继续观察原始元素,直到/除非您断开连接。如果您没有对原始元素做任何事情,那么观察者除了占用内存之外什么也没有做。但同样,如果您要删除该元素,您应该断开观察者的连接。

关于javascript - 删除元素后的 MutationObserver 行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35253565/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com