HTML5新特性之Mutation Observer

1、概述

Mutation Observer(變動觀察器)是監視DOM變動的接口。當DOM對象樹發生任何變動時,Mutation Observer會得到通知。

要概念上,它很接近事件??梢岳斫鉃?,當DOM發生變動會觸發Mutation Observer事件。但是,它與事件有一個本質不同:事件是同步觸發,也就是說DOM發生變動立刻會觸發相應的事件;Mutation Observer則是異步觸發,DOM發生變動以后,并不會馬上觸發,而是要等到當前所有DOM操作都結束后才觸發。

這樣設計是為了應付DOM變動頻繁的情況。舉例來說,如果在文檔中連續插入1000個段落(p元素),會連續觸發1000個插入事件,執行每個事件的回調函數,這很可能造成瀏覽器的卡頓;而Mutation Observer完全不同,只在1000個段落都插入結束后才會觸發,而且只觸發一次。

注:在控制臺可看到log

Mutation Observer有以下特點:

  • 它等待所有腳本任務完成后,才會運行,即采用異步方式
  • 它把DOM變動記錄封裝成一個數組進行處理,而不是一條條地個別處理DOM變動。
  • 它即可以觀察發生在DOM節點的所有變動,也可以觀察某一類變動

目前,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;

2、使用方法

首先,使用MutationObserver構造函數,新建一個實例,同時指定這個實例的回調函數。

var observer = new MutationObserver(callback);

2.1 observer方法

observer方法指定所要觀察的DOM元素,以及要觀察的特定變動。

var article = document.querySelector('article');

var options = {
    'childList': true,
    'arrtibutes': true
};
observer.observer(article, options);

上面代碼首先指定,所要觀察的DOM元素提article,然后指定所要觀察的變動是子元素的變動和屬性變動。最后,將這兩個限定條件作為參數,傳入observer對象的observer方法。

MutationObserver所觀察的DOM變動(即上面代碼的option對象),包含以下類型:

  • childList:子元素的變動
  • attributes:屬性的變動
  • characterData:節點內容或節點文本的變動
  • subtree:所有下屬節點(包括子節點和子節點的子節點)的變動

想要觀察哪一種變動類型,就在option對象中指定它的值為true。需要注意的是,不能單獨觀察subtree變動,必須同時指定childList、attributes和characterData中的一種或多種。

除了變動類型,option對象還可以設定以下屬性:

  • attributeOldValue:值為true或者為false。如果為true,則表示需要記錄變動前的屬性值。
  • characterDataOldValue:值為true或者為false。如果為true,則表示需要記錄變動前的數據值。
  • attributesFilter:值為一個數組,表示需要觀察的特定屬性(比如['class', 'str'])。

2.2 disconnect方法和takeRecord方法

disconnect方法用來停止觀察。發生相應變動時,不再調用回調函數。

  • observer.disconnect();
    takeRecord方法用來清除變動記錄,即不再處理未處理的變動。

  • observer.takeRecord

2.3 MutationRecord對象

DOM對象每次發生變化,就會生成一條變動記錄。這個變動記錄對應一個MutationRecord對象,該對象包含了與變動相關的所有信息。Mutation Observer進行處理的一個個變動對象所組成的數組。

MutationRecord對象包含了DOM的相關信息,有如下屬性:

  • type:觀察的變動類型(attribute、characterData或者childList)。
  • target:發生變動的DOM對象。
  • addedNodes:新增的DOM對象。
  • removeNodes:刪除的DOM對象。
  • previousSibling:前一個同級的DOM對象,如果沒有則返回null。
  • nextSibling:下一個同級的DOM對象,如果沒有就返回null。
  • attributeName:發生變動的屬性。如果設置了attributeFilter,則只返回預先指定的屬性。
  • oldValue:變動前的值。這個屬性只對attribute和characterData變動有效,如果發生childList變動,則返回null。

3、實例

3.1 子元素的變動

下面的例子說明如果讀取變動記錄。

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表示觀察子元素的下級元素)的變動?;卣{函數會在控制臺顯示所有變動的類型和目標元素。

3.2、屬性的變動

下面的例子說明如何追蹤屬性的變動。

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),然后設定記錄變動前的值。實際發生變動時,會將變動前的值顯示在控制臺。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,002評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,400評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,136評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,714評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,452評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,818評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,812評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,997評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,552評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,292評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,510評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,035評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,721評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,121評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,429評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,235評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,480評論 2 379

推薦閱讀更多精彩內容