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
:觀察的變動型別(attribute
、characterData
或者childList
)。target
:發生變動的 DOM 節點。addedNodes
:新增的 DOM 節點。removedNodes
:刪除的 DOM 節點。previousSibling
:前一個同級節點,如果沒有則返回null
。nextSibling
:下一個同級節點,如果沒有則返回null
。attributeName
:發生變動的屬性。如果設定了attributeFilter
,則只返回預先指定的屬性。oldValue
:變動前的值。這個屬性只對attribute
和characterData
變動有效,如果發生childList
變動,則返回null
。
5、示例
監聽文字變動
6、參考連結
- MutationObserver - Web API 介面參考 | MDN (mozilla.org)
- MutationObserver.MutationObserver() - Web API 介面參考 | MDN (mozilla.org)
- MutationObserver.observe() - Web API 介面參考 | MDN (mozilla.org)
- MutationObserverInit - Web API 介面參考 | MDN (mozilla.org)
- MutationRecord - Web API 介面參考 | MDN (mozilla.org)