簡體   English   中英

刪除元素后的 MutationObserver 行為

[英]MutationObserver behavior after the element was removed

我有一個綁定到#foo html 元素的MutationObserver

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后,觀察者停止工作。

  • 這是正常的行為嗎?
  • 那么,我需要再次啟動觀察者嗎?

第三個問題:

  • 第一個觀察者是否被完全移除? 或者,它仍然在運行,只是“什么都不做”? - 我在問這個問題,因為我不希望多個觀察者運行,如果只有一個觀察者在做真正的工作。

並在一秒鍾后再次出現

行為將完全取決於您的意思。

如果您的意思是創建一個具有相同id元素,那么是的,這是預期的行為:當您在一個元素上調用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一個特定元素


這些問題僅在您刪除舊元素並用全新元素替換時才適用:

那么,我需要再次啟動觀察者嗎?

如果您要刪除原始元素並在其位置放置一個新元素,您應該告訴觀察者停止觀察:

observer.disconnect();

一旦你有了一個新元素,你就可以將觀察者連接到它:

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

第一個觀察者是否被完全移除? 或者,它仍然在運行,只是“什么都不做”?

理論上,由於規范明確指出它是引用其觀察者的元素,那么如果您釋放對該元素的唯一引用,理論上觀察者將斷開連接,因為元素及其觀察者列表被清理。 但是,在觀察者沒有對元素的引用的情況下,不清楚如何實現觀察者的disconnect方法,因此它們可能有相互引用。 如果您保留對觀察者的引用,則會將相互引用保留在內存中。 可以肯定的是,我會故意斷開它。

我在問這個問題,因為我不希望多個觀察者運行,如果只有一個觀察者在做真正的工作。

觀察者不會“跑”,他們會做出反應 觀察者將繼續觀察原始元素,直到/除非您斷開它。 如果你沒有對原始元素做任何事情,那么觀察者除了占用內存之外不會做任何事情。 但同樣,如果您要刪除元素,您應該斷開觀察者的連接。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM