我有MutationObserver
绑定到#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
被移除并重新创建后,观察者停止了工作。
第三个问题:
答案 0 :(得分:7)
并在第二次
之后再次出现
这种行为完全取决于你的意思。
如果您的意思是创建了具有相同id
的新元素,那么是,这是预期的行为:当您在元素上调用observer.observe
时,您就是&#39 ;在特定元素上调用它,而不是与其ID匹配的任何元素。如果从DOM中删除该元素并将其替换为另一个看起来相同的元素,则观察者不会神奇地连接到该新的不同元素:
var target = document.querySelector("#foo");
var observer = new MutationObserver(function(mutations) {
snippet.log("#foo was modified");
});
observer.observe(target, {subTree: true, childList: true});
var counter = 0;
tick();
setTimeout(function() {
snippet.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);
}
}
&#13;
<div id="foo">This is the original foo</div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
如果您的意思是将相同的元素重新放回DOM,那么不,这不是预期的行为,而不是在此示例中发生的事情:
var target = document.querySelector("#foo");
var observer = new MutationObserver(function(mutations) {
snippet.log("#foo was modified");
});
observer.observe(target, {subTree: true, childList: true});
var counter = 0;
tick();
setTimeout(function() {
snippet.log("Removing foo for a moment");
target.parentNode.removeChild(target);
setTimeout(function() {
snippet.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);
}
}
&#13;
<div id="foo">This is the original foo</div>
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
&#13;
这里的关键外卖消息是观察者正在观察传递给observe
的一个特定元素。
这些问题仅适用于您删除旧元素并将其替换为全新元素的情况:
那么,我需要再次启动观察者吗?
如果您要删除原始元素并在其中放置一个新元素,您应该告诉观察者停止观察:
observer.disconnect();
获得新元素后,您可以将观察者连接到它:
observer.observe(theNewElement, /*...options go here...*/);
第一个观察者是否完全被移除?或者说,它仍在运行,只是&#34;什么都不做&#34;?
在理论中,由于the spec清楚表明它是引用其观察者的元素,因此如果你释放对该元素的唯一引用,那么理论上观察者因为元素及其观察者列表被清理而断开连接。但是,如果没有观察者对元素的引用,观察者的disconnect
方法如何实现则不清楚,因此它们可能具有相互引用。如果你保留对观察者的引用,那将保持内存中的相互引用。我确实故意断开它。
我问这个问题,因为我不想让多个观察者跑,如果只有其中一个人在做真正的工作。
观察员不要跑步,&#34;他们做出反应。观察者将继续观察原始元素,直到/除非您断开连接。如果你没有对原始元素做任何事情,那么观察者除了占用内存之外不会做任何其他事情。但同样,如果您要删除元素,则应断开观察者的连接。