監聽DOM操作事件
阿新 • • 發佈:2019-01-05
DOMNodeInserted 和 DOMNodeRemoved 事件
在DOM中可以通過DOMNodeInserted和DOMNodeRemoved這兩個事件來監視DOM元素的插入和移除。但由於各瀏覽器中DOM樹的處理方式不同,導致了這兩個事件在各個瀏覽器上都有各自的特點。只要知道了這些特定,使用時做特殊處理就能暫時解決問題。
以下測試是在文件物件上繫結這兩個事件(它們是會冒泡的),並通執行一系列DOM樹的操作:
<script>
addEventListener("DOMContentLoaded",function(){
document.addEventListener ("DOMNodeInserted",function(e) {
console.log("insert",e.target);
});
document.addEventListener("DOMNodeRemoved",function(e) {
console.log("remove",e.target);
});
var div=document.createElement("div");
div.innerHTML="<span>span</span>";
console.log("%cinnerHTML","color:red");
document.body .innerHTML="<div><span>span</span></div>text";
console.log("%cinsertAdjacentHTML","color:red");
document.body.insertAdjacentHTML("beforeend","<div>div</div>");
console.log("%cappendChild","color:red");
document.body.appendChild(div);
document.body.appendChild(div); //重複呼叫 appendChild
console.log("%cremoveChild","color:blue");
document.body.removeChild(div);
console.log("%cinnerHTML","color:blue");
document.body.innerHTML="";
});
</script>
Firefox比Chrome的結果長了許多,首先在 insertAdjacentHTML 時它把已存在的元素都觸發了一次 DOMNodeInserted 但,這些元素並沒有觸發 DOMNodeRemoved ,我覺得此處為Firefox的BUG。另外對於已經存在了的元素執行 appendChild ,即使位置相同Firefox也會先移除這個元素在插入這個元素,所以 DOMNodeInserted 和 DOMNodeRemoved 事件都會被觸發,而Chrome上優化掉了這個操作,所以事件沒有觸發(我覺得這方面Firefox的行為比較正確)。
接下來是IE上的執行結果,這裡使用了IE11上的IE9模式測試:
由於IE不支援控制檯的“%c”命令,所以輸出結果有點難看,不過還是能看懂的。IE對 insertAdjacentHTML 的處理同Chrome,對 appendChild 的處理同Firefox,這些處理我很贊同。但是IE會對插入元素的後代節點都觸發一次 DOMNodeInserted ,我覺得這是不對的,或者說是IE的BUG吧。
總之這兩個事件在Chrome、Firefox、IE上都有各自的問題,使用時需要做一些特殊判斷來處理。最後也希望瀏覽器本身能早日統一這些東西吧。