Mutation Observer(變更觀察器)是監視DOM變更的接口。當DOM對象樹發生任何變更時,Mutation Observer會獲得通知。javascript
要概念上,它很接近事件。能夠理解爲,當DOM發生變更會觸發Mutation Observer事件。可是,它與事件有一個本質不一樣:事件是同步觸發,也就是說DOM發生變更馬上會觸發相應的事件;Mutation Observer則是異步觸發,DOM發生變更之後,並不會立刻觸發,而是要等到當前全部DOM操做都結束後才觸發。html
這樣設計是爲了應付DOM變更頻繁的狀況。舉例來講,若是在文檔中連續插入1000個段落(p元素),會連續觸發1000個插入事件,執行每一個事件的回調函數,這極可能形成瀏覽器的卡頓;而Mutation Observer徹底不一樣,只在1000個段落都插入結束後纔會觸發,並且只觸發一次。java
注:在控制檯可看到logreact
Mutation Observer有如下特色:數組
目前,Firefox(14+)、Chrome(26+)、Opera(15+)、IE(11+)和Safari(6.1+)支持這個API。Safari 6.0和Chrome 18-25使用這個API的時候,須要加上WebKit前綴(WebKitMutationObserver)。可使用下面的表達式檢查瀏覽器是否支持這個API。瀏覽器
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver; var mutationObserverSupport = !!MutationObserver;
首先,使用MutationObserver構造函數,新建一個實例,同時指定這個實例的回調函數。less
var observer = new MutationObserver(callback);
observer方法指定所要觀察的DOM元素,以及要觀察的特定變更。dom
var article = document.querySelector('article'); var options = { 'childList': true, 'arrtibutes': true }; observer.observer(article, options);
上面代碼首先指定,所要觀察的DOM元素提article,而後指定所要觀察的變更是子元素的變更和屬性變更。最後,將這兩個限定條件做爲參數,傳入observer對象的observer方法。異步
MutationObserver所觀察的DOM變更(即上面代碼的option對象),包含如下類型:函數
想要觀察哪種變更類型,就在option對象中指定它的值爲true。須要注意的是,不能單獨觀察subtree變更,必須同時指定childList、attributes和characterData中的一種或多種。
除了變更類型,option對象還能夠設定如下屬性:
disconnect方法用來中止觀察。發生相應變更時,再也不調用回調函數。
observer.disconnect();
takeRecord方法用來清除變更記錄,即再也不處理未處理的變更。
observer.takeRecord
DOM對象每次發生變化,就會生成一條變更記錄。這個變更記錄對應一個MutationRecord對象,該對象包含了與變更相關的全部信息。Mutation Observer進行處理的一個個變更對象所組成的數組。
MutationRecord對象包含了DOM的相關信息,有以下屬性:
下面的例子說明若是讀取變更記錄。
var callback = function(records) { records.map(function(record) { console.log('Mutation type: ' + record.type); console.log('Mutation target: ' + record.target); }); }; var mo = new MutationObserver(callback); var option = { 'childList': true, 'subtree': true }; mo.observer(document.body, option);
上面代碼的觀察器,觀察body元素的全部下級元素(childList表示觀察子元素,subtree表示觀察子元素的下級元素)的變更。回調函數會在控制檯顯示全部變更的類型和目標元素。
下面的例子說明如何追蹤屬性的變更。
var callback = function(records) { records.map(function(record) { console.log('Previous attribute value: ' + record.oldValue); }); }; var mo = new MutationObserver(callback); var element = document.getElementById('#my_element'); var option = { 'attribute': true, 'attributeOldValue': true }; mo.observer(element, option);
上面代碼先設定追蹤屬性變更('attributes': true),而後設定記錄變更前的值。實際發生變更時,會將變更前的值顯示在控制檯。
[1] Tiffany Brown, Getting to know mutation observers
[2] Michal Budzynski, JavaScript: The less know parts.DOM Mutations
[3] Jeff Griffiths, DOM MutationObserver - reacting to DOM changes without killing browser performance
[4] Ruanyf, Mutation Observer