簡體   English   中英

為什么 MutationObserver 為 childList 觸發兩次但從未為 characterData 觸發?

[英]Why does MutationObserver fire twice for childList but never for characterData?

我有一個簡單的MutationObserver設置作為測試。 HTML 有一個span其文本內容每秒更新一次(以及一個div用於消息):

<span class="tester"></span>
<div id="msg"></div>

MutationObserver 設置為觀察.tester並在觀察到變化時將文本寫入#msg div 同時, setInterval()每秒運行一次以更改.tester的文本:

var target = document.querySelector('.tester');

var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    console.log(mutation.type);
    $('#msg').append(mutation.type+"<br/>")
    setTimeout(function() { $('#msg').text(''); }, 500);
  });    
});

var config = { attributes: true, childList: true, characterData: true };
observer.observe(target, config);

setInterval(function() {
  $('#msg').text('');
  $('.tester').text("update: "+Math.random())
}, 1000);

我希望此代碼每秒打印一次字符數據已更改。 根據Mozilla 的 MutationObserver 文檔,它說到 characterData:“如果要觀察到目標數據的突變,則設置為 true。” 相反,我看不出有什么characterData突變,但確實看到兩個的childList突變每一秒。

為什么我沒有看到任何 characterData 突變,為什么我看到了兩個childList 突變?

這是CodePen的一個工作示例。

原因正如Jeremy Banks 所說:當您使用 jQuery 的text() ,它會刪除所有文本節點,然后添加新節點。 這不是對字符數據的更改,而是對childList的更改:刪除那里的節點並用新節點替換它。

要查看字符數據的更改,您必須修改現有文本節點的nodeValue觀察subtree修改:

 var target = document.querySelector('.tester'); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { console.log(mutation.type); $('#msg').append(mutation.type+"<br/>") setTimeout(function() { $('#msg').text(''); }, 500); }); }); var config = { attributes: true, childList: true, characterData: true, subtree: true // <=== Change, added subtree }; observer.observe(target, config); var timer = setInterval(function() { $('#msg').text(''); // Change --VVVVV modifying the existing child node $('.tester')[0].firstChild.nodeValue = "updated" + Math.random(); }, 1000); // Stop after 10 seconds setTimeout(function() { clearInterval(timer); }, 10000);
 <span class="tester">x</span><!-- Change, added a starting child node --> <div id="msg"></div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>


關於為什么有兩個childList突變的問題,是的,我認為您是對的:他們正在刪除孩子,然后添加一個新的孩子。 如果我們使用replaceChild方法,我們只會看到一個突變:

 var target = document.querySelector('.tester'); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { console.log(mutation.type); $('#msg').append(mutation.type+"<br/>") setTimeout(function() { $('#msg').text(''); }, 500); }); }); var config = { attributes: true, childList: true, characterData: true, subtree: true // <=== Change, added subtree }; observer.observe(target, config); var timer = setInterval(function() { $('#msg').text(''); // Change --VVVVV modifying the existing child node var text = document.createTextNode("updated" + Math.random()); var parent = $('.tester')[0]; parent.replaceChild(text, parent.firstChild); }, 1000); // Stop after 10 seconds setTimeout(function() { clearInterval(timer); }, 10000);
 <span class="tester">x</span><!-- Change, added a starting child node --> <div id="msg"></div> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

暫無
暫無

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

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