MutationObserver 監聽DOM樹變化

1 概述

Mutation observer 是用於代替 Mutation events 做爲觀察DOM樹結構發生變化時,作出相應處理的API。爲何要使用mutation observer 去代替 mutation events 呢,咱們先了解一下mutation eventsjavascript

Mutation Events

Mutation events 是在 DOM3中定義,用於監聽DOM樹結構變化的事件java

它簡單的用法以下:數組

document.getElementById('list').addEventListener("DOMSubtreeModified", function(){ console.log('列表中子元素被修改'); }, false);

Mutation 事件列表瀏覽器

  • DOMAttrModified
  • DOMAttributeNameChanged
  • DOMCharacterDataModified
  • DOMElementNameChanged
  • DOMNodeInserted
  • DOMNodeRemoved
  • DOMNodeInsertedIntoDocument
  • DOMSubtreeModified

其中DOMNodeRemoved,DOMNodeInserted 和 DOMSubtreeModified 分別用於 監聽元素子項的刪除,新增,修改(包括刪除和新增),
DOMAttrModified 是監聽元素屬性的修改,而且可以提供具體的修改動做。異步

Mutation Events遇到的問題
  • 瀏覽器兼容性問題
    IE9不支持Mutation Events
    Webkit內核不支持DOMAttrModified特性,
    DOMElementNameChanged和DOMAttributeNameChanged 在Firefox上不被支持。
  • 性能問題
    1.Mutation Events是同步執行的,它的每次調用,都須要從事件隊列中取出事件,執行,而後事件隊列中移除,期間須要移動隊列元素。若是事件觸發的較爲頻繁的話,每一次都須要執行上面的這些步驟,那麼瀏覽器會被拖慢。
    2.Mutation Events自己是事件,因此捕獲是採用的是事件冒泡的形式,若是冒泡捕獲期間又觸發了其餘的MutationEvents的話,頗有可能就會致使阻塞Javascript線程,甚至致使瀏覽器崩潰。

Mutation Observer

Mutation Observer 是在DOM4中定義的,用於替代 mutation events 的新API,它的不一樣於events的是,全部監聽操做以及相應處理都是在其餘腳本執行完成以後異步執行的,而且是因此變更觸發以後,將變得記錄在數組中,統一進行回調的,也就是說,當你使用observer監聽多個DOM變化時,而且這若干個DOM發生了變化,那麼observer會將變化記錄到變化數組中,等待一塊兒都結束了,而後一次性的從變化數組中執行其對應的回調函數。函數

Mutation Observer 的瀏覽器兼容範圍性能


兼容性

2 方法

構造函數

用來實例化一個Mutation觀察者對象,其中的參數是一個回調函數,它是會在指定的DOM節點發送變化後,執行的函數,而且會被傳入兩個參數,一個是變化記錄數組(MutationRecord),另外一個是觀察者對象自己ui

new MutationObserver(function(records, itself){});
observe

在觀察者對象上,註冊須要觀察的DOM節點,以及相應的參數spa

void observe(Node target, optional MutationObserverInit options)

其中的可選參數 MutationObserverInit的屬性以下:線程

childLIst 觀察目標節點的子節點的新增和刪除。
attributes 觀察目標節點的屬性節點(新增或刪除了某個屬性,以及某個屬性的屬性值發生了變化)。
characterData 若是目標節點爲characterData節點(一種抽象接口,具體能夠爲文本節點,註釋節點,以及處理指令節點)時,也要觀察該節點的文本內容是否發生變化
subtree 觀察目標節點的全部後代節點(觀察目標節點所包含的整棵DOM樹上的上述三種節點變化)
attributeOldValue 在attributes屬性已經設爲true的前提下, 將發生變化的屬性節點以前的屬性值記錄下來(記錄到下面MutationRecord對象的oldValue屬性中)
characterDataOldValue 在characterData屬性已經設爲true的前提下,將發生變化characterData節點以前的文本內容記錄下來(記錄到下面MutationRecord對象的oldValue屬性中)
attributeFilter 一個屬性名數組(不須要指定命名空間),只有該數組中包含的屬性名發生變化時纔會被觀察到,其餘名稱的屬性發生變化後會被忽略想要設置那些刪選參數的話,

若是想要使用哪一個參數的話,就將其值設定爲true

disconnect

暫定在觀察者對象上設置的節點的變化監聽,直到從新調用observe方法

takeRecords

在觀察者對象上調用takeRecords 會返回 其觀察節點上的變化記錄(MutationRecord)數組
其中MutationRecord數組也會做爲,觀察者初始化時的回調函數的第一個參數
其包含的屬性以下:

type 若是是屬性發生變化,則返回attributes.若是是一個CharacterData節點發生變化,則返回characterData,若是是目標節點的某個子節點發生了變化,則返回childList.
target 返回這次變化影響到的節點,具體返回那種節點類型是根據type值的不一樣而不一樣的,若是type爲attributes,則返回發生變化的屬性節點所在的元素節點,若是type值爲characterData,則返回發生變化的這個characterData節點.若是type爲childList,則返回發生變化的子節點的父節點.
addedNodes 返回被添加的節點
removedNodes 返回被刪除的節點
previousSibling 返回被添加或被刪除的節點的前一個兄弟節點
nextSibling 返回被添加或被刪除的節點的後一個兄弟節點
attributeName 返回變動屬性的本地名稱
oldValue 根據type值的不一樣,返回的值也會不一樣.若是type爲attributes,則返回該屬性變化以前的屬性值.若是type爲characterData,則返回該節點變化以前的文本數據.若是type爲childList,則返回null

3 使用實例

// Firefox和Chrome早期版本中帶有前綴 var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver // 選擇目標節點 var target = document.querySelector('#some-id'); // 建立觀察者對象 var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { console.log(mutation.type); }); }); // 配置觀察選項: var config = { attributes: true, childList: true, characterData: true } // 傳入目標節點和觀察選項 observer.observe(target, config); // 隨後,你還能夠中止觀察 observer.disconnect();

4 參考連接

[1].MDN Mutation Observer
[2].將突變事件和屬性更改事件遷移到突變觀察者



文/falm(簡書做者) 原文連接:http://www.jianshu.com/p/b5c9e4c7b1e1 著做權歸做者全部,轉載請聯繫做者得到受權,並標註「簡書做者」。
相關文章
相關標籤/搜索