1、概述

MutationObserver介面提供了監視對DOM樹所做更改的能力。它被設計為舊的Mutation Events功能的替代品,該功能是DOM3 Events規範的一部分。

但是,它與Mutation Events事件有一個本質不同:事件是同步觸發,也就是說,DOM 的變動立刻會觸發相應的事件;Mutation Observer 則是非同步觸發,DOM 的變動並不會馬上觸發,而是要等到當前所有 DOM 操作都結束才觸發。

Mutation Observer 有以下特點:

非同步觸發方式

它把 DOM 變動記錄封裝成一個數組進行處理,而不是一條條個別處理 DOM 變動。

它既可以觀察 DOM 的所有型別變動,也可以指定只觀察某一類變動。

2、MutationObserver()建構函式

使用時,會使用MutationObserver建構函式建立並返回一個新的 MutationObserver例項, 它會在指定的DOM發生變化時被呼叫。

const observer = new MutationObserver(callback);

上面程式碼中的callback函式,會在每次 DOM 變動後呼叫。該回調函式接受兩個引數,第一個是變動陣列,第二個是觀察器例項,下面是一個例子。

function callback(mutationList, observer) {
mutationList.forEach((mutation) => {
switch(mutation.type) {
case 'childList':
/* 從樹上新增或移除一個或更多的子節點;參見 mutation.addedNodes 與
mutation.removedNodes */
break;
case 'attributes':
/* mutation.target 中某節點的一個屬性值被更改;該屬性名稱在 mutation.attributeName 中,
該屬性之前的值為 mutation.oldValue */
break;
}
});
}
const observer = new MutationObserver(callback);

3、MutationObserver例項的方法

3.1、 observe()

observe方法用來啟動監聽,它接受兩個引數:

  • 第一個引數:所要觀察的 DOM 節點
  • 第二個引數:一個配置物件,指定所要觀察的特定變動
// 得到要觀察的元素
const elementToObserve = document.querySelector("#targetElementId"); // 建立一個叫 `observer` 的新 `MutationObserver` 例項,
// 並將回撥函式傳給它
const observer = new MutationObserver(function() {
console.log('callback that runs when observer is triggered');
}); // 在 MutationObserver 例項上呼叫 `observe` 方法,
// 並將要觀察的元素與選項傳給此方法
const conf = {
subtree: true,
childList: true
}
observer.observe(elementToObserve, conf);

上面程式碼中,observe方法接受兩個引數,第一個是所要觀察的DOM元素是elementToObserve,第二個是所要觀察的變動型別(一個可選的MutationObserverInit 物件)。

觀察器所能觀察的 DOM 變動型別(即上面程式碼的conf物件),有以下幾種。

  • childList:子節點的變動(指新增,刪除或者更改)。
  • attributes:屬性的變動。
  • characterData:節點內容或節點文字的變動。

想要觀察哪一種變動型別,就在conf物件中指定它的值為true。 提醒:三種類型必須有一個為true,否則會丟擲 TypeError 異常

下面時所有的conf配置項:

  • attributeFilter可選:要監視的特定屬性名稱的陣列。如果未包含此屬性,則對所有屬性的更改都會觸發變動通知。無預設值。

  • attributeOldValue可選:當監視節點的屬性改動時,將此屬性設為 true 將記錄任何有改動的屬性的上一個值。有關觀察屬性更改和值記錄的詳細資訊。無預設值。

  • attributes 可選:設為 true 以觀察受監視元素的屬性值變更。預設值為 false

  • characterData可選:設為 true 以監視指定目標節點或子節點樹中節點所包含的字元資料的變化。無預設值。

  • characterDataOldValue可選:設為 true 以在文字在受監視節點上發生更改時記錄節點文字的先前值。無預設值。

  • childList可選:設為 true 以監視目標節點(如果 subtree 為 true,則包含子孫節點)新增或刪除新的子節點。預設值為 false

  • subtree可選:設為 true 以將監視範圍擴充套件至目標節點整個節點樹中的所有節點。MutationObserverInit 的其他值也會作用於此子樹下的所有節點,而不僅僅只作用於目標節點。預設值為 false

3.2、 disconnect()

disconnect方法用來停止觀察。呼叫該方法後,DOM 再發生變動,也不會觸發觀察器。

observer.disconnect();

3.3、 takeRecords()

從MutationObserver的通知佇列中刪除所有待處理的通知,並將它們返回到[MutationRecord]

observer.takeRecords();

4、MutationRecord 物件

DOM 每次發生變化,就會生成一條變動記錄(MutationRecord 例項)。該例項包含了與變動相關的所有資訊。Mutation Observer 處理的就是一個個MutationRecord例項所組成的陣列。

MutationRecord物件包含了DOM的相關資訊,有如下屬性:

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

5、示例

監聽文字變動

6、參考連結