1. 程式人生 > >監聽DOM操作事件

監聽DOM操作事件

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>

DOM操作後臺輸出資料

Firefox比Chrome的結果長了許多,首先在 insertAdjacentHTML 時它把已存在的元素都觸發了一次 DOMNodeInserted 但,這些元素並沒有觸發 DOMNodeRemoved ,我覺得此處為Firefox的BUG。另外對於已經存在了的元素執行 appendChild ,即使位置相同Firefox也會先移除這個元素在插入這個元素,所以 DOMNodeInserted 和 DOMNodeRemoved 事件都會被觸發,而Chrome上優化掉了這個操作,所以事件沒有觸發(我覺得這方面Firefox的行為比較正確)。

Firefox下得資料輸出

接下來是IE上的執行結果,這裡使用了IE11上的IE9模式測試:
由於IE不支援控制檯的“%c”命令,所以輸出結果有點難看,不過還是能看懂的。IE對 insertAdjacentHTML 的處理同Chrome,對 appendChild 的處理同Firefox,這些處理我很贊同。但是IE會對插入元素的後代節點都觸發一次 DOMNodeInserted ,我覺得這是不對的,或者說是IE的BUG吧。

總之這兩個事件在Chrome、Firefox、IE上都有各自的問題,使用時需要做一些特殊判斷來處理。最後也希望瀏覽器本身能早日統一這些東西吧。