MutationObserver 介面
MutationObserver 介面
可以在 DOM 被修改時非同步執行回撥。使用 MutationObserver 可以觀察整個文件、DOM樹的一部分,可以觀察元素屬性、子節點、文字的變化。
需要先建立 MutationObserver 建構函式並傳入一個回撥函式:
let observer = new MutationObserver(() => console.log("DOM 改變"));
observe() 方法
使用 observe()
方法與 DOM 關聯起來,接收兩個必需引數:要觀察變化的 DOM 節點,一個 MutationObserverInit 物件。
let observer = new MutationObserver(() => console.log("xkc div -- attributes changed"));
let xkcDiv = document.createElement("div");
document.body.appendChild(xkcDiv);
observer.observe(xkcDiv, { attributes: true });
xkcDiv.setAttribute("id", "xkc");
console.log("Synchronization task");
/**
* Synchronization task
* xkc div -- attributes changed
*/
由於 MutationObserver 中的回撥是非同步回撥,因此會先執行其他所有的同步任務。
傳入回撥函式的第一個引數是一個 MutationRecord 例項。
每個回撥都會收到一個 MutationRecord 例項的陣列。其中包括一些 DOM 發生的改變資訊。每次執行回撥都會傳入一個 MutationRecord 的例項,與執行的順序所對應。
// 清空 body 內容
document.body.innerHTML = "";
let observer1 = new MutationObserver((MutationRecord) =>
console.log(MutationRecord)
);
let xkcDiv1 = document.createElement("div");
document.body.appendChild(xkcDiv1);
observer1.observe(xkcDiv1, { attributes: true });
xkcDiv1.setAttribute("id", "xkc");
/**
[
{
ddedNodes: NodeList [],
attributeName: "id",
attributeNamespace: null,
nextSibling: null,
oldValue: null,
previousSibling: null,
removedNodes: NodeList [],
target: div#xkc,
type: "attributes"
}
]
*/
連續修改會生成多個 MutationRecord 例項。
xkcDiv1.setAttribute("name", "xkc");
xkcDiv1.setAttribute("age", "20");
/*
[
{
addedNodes: NodeList [],
attributeName: "id",
attributeNamespace: null,
nextSibling: null,
oldValue: null,
previousSibling: null,
removedNodes: NodeList [],
target: div#xkc,
type: "attributes"
},
{
addedNodes: NodeList [],
attributeName: "name",
attributeNamespace: null,
nextSibling: null,
oldValue: null,
previousSibling: null,
removedNodes: NodeList [],
target: div#xkc,
type: "attributes"
},
{
addedNodes: NodeList [],
attributeName: "age",
attributeNamespace: null,
nextSibling: null,
oldValue: null,
previousSibling: null,
removedNodes: NodeList [],
target: div#xkc,
type: "attributes"
}
]
*/
MutationRecord 例項的屬性
屬性 | 說明 |
---|---|
target | 被修改影響的目標節點 |
type | 字串,表示變化的型別:“attributes”、“characterData” 或 “childList” |
oldValue | 如果在 MutationObserverInit 物件中啟用(attributeOldValue 或 characterData OldValue 為 true),“attributes” 或 “characterData” 的變化事件會設定這個屬性為被替代的值,“childList” 型別的變化始終將這個屬性設定為 null |
attributeName | 對於 “attributes” 型別的變化,儲存被修改屬性的名稱,其他變化事件這個屬性為 null |
attributeNamespace | 對於使用名稱空間的 “attributes” 型別的變化,這裡儲存被修改屬性的名稱,其他變化事件這個屬性為 null |
addedNodes | 對於 “childList” 型別的變化,返回包含變化中新增的節點的 NodeList,預設為空 NodeList |
removedNodes | 對於 “childList” 型別的變化,返回包含變化中刪除的節點的 NodeList ,預設為空 NodeList |
previousSibling | 對於 “childList” 型別的變化,返回變化的節點的前一個同胞 Node ,預設為 null |
nextSibling | 對於 “childList” 型別的變化,返回變化的節點的最後一個同胞 Node ,預設為 null |
傳入回撥函式的第二個引數是一個觀察變化的 MutationObserver 的例項。
// 清空 body 內容
document.body.innerHTML = "";
let observer2 = new MutationObserver((mutationRecord, mutationObserver) => {
console.log(mutationRecord, mutationObserver);
});
let xkcDiv2 = document.createElement("div");
document.body.appendChild(xkcDiv2);
observer2.observe(xkcDiv2, { attributes: true });
xkcDiv2.setAttribute("id", "xkc");
// [MutationRecord] MutationObserver
disconnect() 方法
預設情況下,只要觀察的元素不被垃圾回收, MutationObserver 的回撥就會響應 DOM 變化事件,而被執行。想要提前終止執行回撥,可以使用 disconnect()
方法。
// 清空 body 內容
document.body.innerHTML = "";
let observer3 = new MutationObserver(() =>
console.log("xkc div -- attributes changed")
);
let xkcDiv3 = document.createElement("div");
document.body.appendChild(xkcDiv3);
observer3.observe(xkcDiv3, { attributes: true });
xkcDiv3.setAttribute("id", "xkc");
// 終止
observer3.disconnect();
xkcDiv3.setAttribute("name", "xkc");
// 無任何列印輸出
同步使用 disconnect()
方法之後,不僅會停止此後變化事件的回撥,也會拋棄已經加入任務佇列中的非同步回撥。
想要讓加入到任務佇列中的非同步回撥執行,可使用 setTimeout()
讓已經入列的回撥執行完畢再呼叫 disconnect()
// 清空 body 內容
document.body.innerHTML = "";
let observer4 = new MutationObserver(() =>
console.log("xkc div -- attributes changed")
);
let xkcDiv4 = document.createElement("div");
document.body.appendChild(xkcDiv4);
observer4.observe(xkcDiv4, { attributes: true });
xkcDiv4.setAttribute("id", "xkc");
// setTimeout
setTimeout(() => {
// 終止
observer4.disconnect();
xkcDiv4.setAttribute("name", "xkc");
}, 0);
/*
[
{
addedNodes: NodeList [],
attributeName: "id",
attributeNamespace: null,
nextSibling: null,
oldValue: null,
previousSibling: null,
removedNodes: NodeList [],
target: div#xkc,
type: "attributes"
}
]
*/
MutationObserverInit 與觀察範圍
屬性 | 說明 |
---|---|
subtree | 布林值,表示除了目標節點,是否觀察目標節點的子樹。如果是 false ,則只觀察目標節點變化,如果是 true,則觀察目標節點和其子樹。預設為 false |
attributes | 布林值,表示是否觀察目標節點的屬性變化。預設為 false |
attributeFilter | 字串陣列。表示要觀察的那些屬性的變化。設定為 true 時,也會將 attributes 設為 true,預設觀察所有屬性 |
attributeOldValue | 布林值,表示 MutationRecord 是否記錄變化之前的屬性值,設定為 true 時,也會將 attributes 設為 true ,預設為 false |
characterData | 布林值,表示修改字元資料是否觸發變化事件,預設為 false |
characterDataOldValue | 布林值,表示 MutationRecord 是否記錄變化之前的字元資料,設定為 true 時,也會將 characterData 設為 true,預設為 false |
childList | 布林值,表示修改目標節點的子節點是否觸發變化事件,預設為 false |
takeRecords() 方法
呼叫 MutationObserver 例項的 takeRecords()
方法可以清空記錄列隊,取出並返回其中的所有 MutationRecord 例項。
let observer = new MutationObserver((mutationRecords) => console.log(mutationRecords));
observer.observe(document.body, { attributes: true });
document.body.className = "xkc";
document.body.className = "strive";
console.log(observer.takeRecords());
console.log(observer.takeRecords());
// [MutationRecord, MutationRecord]
// []
相關文章
- MutationObserver監聽DOM變化示例Server
- MutationObserver、Worker 、MessageChannel也只是API的使用而已ServerAPI
- 來一波原生的觀察者模式 | MutationObserver模式Server
- JavaScript 工作原理之十-使用 MutationObserver 監測 DOM 變化JavaScriptServer
- 監聽DOM載入完成及改變——MutationObserver應用Server
- JavaScript是如何工作的:使用MutationObserver跟蹤DOM的變化JavaScriptServer
- 實現頁面水印,到底跟MutationObserver有什麼關係?Server
- [譯] JavaScript 是如何運作的:用 MutationObserver 追蹤 DOM 的變化JavaScriptServer
- 介面卡模式(類介面卡,物件介面卡,介面介面卡)模式物件
- Lock介面之Condition介面
- API介面------外部介面和內部介面區別API
- java 介面,介面的特性,介面實現多型,面向介面程式設計Java多型程式設計
- 類與介面(三)java中的介面與巢狀介面Java巢狀
- 『居善地』介面測試 — 2、介面和介面文件概念
- 介面卡模式(類介面卡 物件介面卡)模式物件
- 什麼是介面?如何定義介面?如何實現介面?
- 介面
- 介面測試--介面文件規範
- 1688商品詳情資料介面、商品列表介面,商品屬性介面、商品優惠券介面
- 淘寶商品詳情介面(商品銷量介面,商品列表介面,商品影片介面)程式碼展示
- RPC介面和http介面的區別RPCHTTP
- 開啟系統介面/軟體介面
- Java 自學 - 介面與繼承 介面Java繼承
- 視窗介面設計規範:介面關閉方式及介面疊加
- 介面供應商提供的AG介面BB IN介面對接文件demo教程
- 2.4 介面
- Collection介面
- AddUserDao介面
- TS — 介面
- TS 介面
- go介面Go
- ImportSelector介面Import
- TypeScript 介面TypeScript
- 介面1
- Serializable介面
- 介面3
- IO介面
- dubbo介面