如何來監聽dom變化?
工作中突然有一個需求,必須你要監聽dom的插入,那麼就需要去監聽dom變化。在一般印象中,監聽事件應該是這麼實現的比如 xx.addEventListener(xxx)。而實際上關於這個dom變化有一套html5標準。如在mdn寫到MutationObserver接口提供了監視對DOM樹所做更改的能力。它被設計為舊的Mutation Events功能的替代品,該功能是DOM3 Events規範的一部分。
使用方法 var observer = new MutationObserver(callback); 該構造函數會在指定dom事件觸發的時候,調用回調函數。callback方法有2個參數,一個是描述所有被觸發改動的 MutationRecord 對象數組,另一個是調用該函數的MutationObserver 對象。第一個屬性比較重要,返回了改變的信息。
然後調用observer.observe(targetNode, observerOptions);該方法配置了 MutationObserver 對象的回調方法以開始接收與給定選項匹配的DOM變化的通知。根據配置,觀察者會觀察 DOM 樹中的單個 Node,也可能會觀察被指定節點的部分或者所有的子孫節點。 observerOptions記錄了選項設置。支持{attributeFilter, attributeOldValue, attributes, characterData, characterDataOldValue, childList ,subtree}。值得注意的是:當調用 observe() 方法時,childList,attributes 或者 characterData 三個屬性之中,至少有一個必須為 true,否則會拋出 TypeError 異常。要停止 MutationObserver(以便不再觸發它的回調方法),需要調用MutationObserver.disconnect()方法。
舉個詳細點的例子。一個頁面我需要在它其他元素沒有超過客戶端高度的時候,給底部容易加以fixed布局。因為這樣的話body後面就不會有空白。而內部容器是有可能實時變化的(元素插入或者刪除)。這樣就需要這個方法去監聽變化。
const callback = function (mutations, ob) { for (let mutation of mutations) { if (mutation.type === 'childList') { resizeHandler(); //設置屬性style } } }; const targetNode = document.body; const observerOptions = { childList: true, // 觀察目標子節點的變化,是否有添加或者刪除 subtree: true // 觀察後代節點,默認為 false } const observer = new MutationObserver(callback); observer.observe(targetNode, observerOptions);因為監聽功能很強大,如果每次記錄屬性變化是非常複雜的,如果胡亂使用屬性監聽,瀏覽器會卡死。這裡就一般記錄節點。如果你的內容操作不是通過插入節點,而是修改屬性的話,這個監聽就會失效了。而這裡的頁面一般是自己製作的,不會有什麼問題。
給你代碼|往期回顧:
擴展的上傳與更新|給你代碼
隨機密碼生成器|給你代碼
你是否像我一樣排斥Composer?|給你代碼