MutationObserver
物件
MutationObserver 是一個用來追蹤 DOM 變化的物件,它可以監聽 DOM 的變化,並且在變化發生時執行指定的 Callback Function。
它本身是一個建構函式,所以我們需要用 new 關鍵字來建立實體,建立時需要傳入一個 Callback Function 作為參數,並使用 observe() 方法來設定觀察目標和觀察選項。
以下是一個簡單的範例,當按下按鈕時,會在 #countContainer 內新增一個 span 元素,並且在控制台印出 "DOM被修改了":
//html
0
修改文字
//Javascript
const observer = new MutationObserver(function(){
console.log('DOM被修改了');
});
observer.observe(document.querySelector('body'), {
childList: true,
subtree: true,
characterData: true
});
var count = 0;
document.querySelector('#btn').addEventListener('click', function(){
count++;
document.querySelector('#countContainer').innerHTML += `${count} `;
});
MutationObserver 的 Function 參數可以接到由 MutationObserver 提供的 MutationRecords 陣列和 MutationObserver 實體作為參數:
records :這是一個陣列,裡面包含了所有被觀察的節點的變化紀錄。
observer :這是 MutationObserver 的實體,這最常用來切斷 observer 的連結。
語法:
const observer = new MutationObserver(function (records, observer) {
console.log(records, observer);
});
records 參數的說明請見 observe(),observer 參數的說明請見 disconnect()。
observe()
方法
observe() 方法用來設定 MutationObserver 的觀察目標和觀察選項,它有兩個參數:
target :要觀察的目標節點。
options :一個物件,用來設定觀察選項。
而 options 物件有以下屬性:
childList :是否觀察子節點的增減,預設為 false。
attributes :是否觀察節點的屬性變化,預設為 false。
characterData :是否觀察節點的文字內容變化,預設為 false。
subtree :是否觀察目標節點的所有子節點,預設為 false。
attributeOldValue :是否在屬性變化時記錄舊的屬性值,預設為 false。
characterDataOldValue :是否在文字內容變化時記錄舊的文字內容,預設為 false。
attributeFilter :一個陣列,用來設定要觀察的屬性名稱,預設為空陣列。
語法:
observer.observe(target, options);
以下範例判斷 DOM 的變化類型,並且在控制台印出相對應的訊息:
//HTML
原始內容
修改節點
修改文字
//Javascript
const observer = new MutationObserver(function(records, observer) {
for(let record of records) {
if (record.type === 'childList') {
console.log('DOM被修改了');
}
else if (record.type === 'characterData') {
console.log('文字被修改了');
}
}
});
observer.observe(document.querySelector('body'), {
childList: true,
subtree: true,
characterData: true
});
const contentBox = document.querySelector('#contentBox');
document.querySelector('#changeDOM').addEventListener('click', function(){
contentBox.innerText = 'DOM被修改了';
});
document.querySelector('#changeText').addEventListener('click', function(){
contentBox.firstChild.textContent = '文字被修改了';
});
disconnect()
方法
disconnect() 方法用來切斷 MutationObserver 的連結,這樣就不會再觀察到任何變化,它沒有參數,語法如下:
observer.disconnect();
以下範例在按下按鈕時,會切斷 MutationObserver 的連結,這樣就不會再觀察到任何變化:
//HTML
這是範例文字
修改#myNode的內容
斷開MutationObserver連接
//Javascript
const myNode = document.querySelector('#myNode');
const result = document.querySelector('#result');
const observer = new MutationObserver(function(records, observer) {
result.innerHTML += 'DOM被修改了 ';
});
observer.observe(myNode, {
childList: true,
subtree: true,
characterData: true
});
document.querySelector('#editMyNode').addEventListener('click', function(){
myNode.innerHTML = '這是修改後的文字';
});
document.querySelector('#disconnectObserver').addEventListener('click', function(){
observer.disconnect();
});
如果需要再次觀察變化,可以再次使用 observe() 方法來設定觀察目標和觀察選項。
另外,disconnect() 方法也可以在 MutationObserver 的 Function 內使用,這樣就可以在觸發變化時切斷連結:
const observer = new MutationObserver(function(records, observer) {
//...
observer.disconnect();
});