MutationObserver: observe() 方法
MutationObserver 的 observe() 方法用於配置 MutationObserver 的回撥,使其開始接收與給定選項匹配的 DOM 更改通知。
根據配置,觀察者可以監視 DOM 樹中的單個 Node,或者監視該節點及其部分或全部後代節點。同一個節點可以被多個觀察者監視,同一個 MutationObserver 可以透過多次呼叫 observe() 來監視 DOM 樹不同部分或不同型別的更改。
要停止 MutationObserver(使其不再觸發任何回撥),請呼叫 MutationObserver.disconnect()。
語法
observe(target, options)
引數
目標options-
一個物件,提供描述哪些 DOM 變異應該報告給
mutationObserver的callback的選項。在呼叫observe()時,至少必須將childList、attributes和/或characterData中的一個設定為true。否則,將丟擲TypeError異常。選項如下:
subtree可選-
設定為
true可將監視範圍擴充套件到以target為根的整個節點子樹。所有其他屬性也將擴充套件到子樹中的所有節點,而不僅僅應用於target節點。預設值為false。請注意,如果target的後代節點被移除,該後代子樹中的更改將繼續被觀察,直到關於移除本身的通知被傳遞為止。 childList可選-
設定為
true可監視目標節點(如果subtree為true,則監視其後代節點)的子節點新增或現有子節點移除。預設值為false。 attributes可選-
設定為
true可監視被監視節點上屬性值的更改。預設值為true,如果指定了attributeFilter或attributeOldValue中的任何一個,否則預設值為false。 attributeFilter可選-
要監視的特定屬性名稱陣列。如果未包含此屬性,則所有屬性的更改都會導致變異通知。
attributeOldValue可選-
設定為
true可記錄監視節點屬性值更改時任何屬性的先前值;有關監視屬性更改並記錄值的示例,請參見 監視屬性值。預設值為false。 characterData可選-
設定為
true可監視指定的節點(如果subtree為true,則監視其後代節點)中包含的字元資料的更改。預設值為true,如果指定了characterDataOldValue,否則預設值為false。 characterDataOldValue可選-
設定為
true可記錄被監視節點文字值更改時的先前文字值。預設值為false。
返回值
無(undefined)。
異常
TypeError-
在以下任何情況下丟擲
options的配置導致實際上沒有任何內容被監視。(例如,如果childList、attributes和characterData都為false。)options.attributes的值為false(表示不監視屬性更改),但attributeOldValue為true和/或attributeFilter存在。characterDataOldValue選項為true但characterData為false(表示不監視字元更改)。
示例
基本用法
在此示例中,我們演示瞭如何在設定好 MutationObserver 例項後,呼叫其 observe() 方法,並傳入一個目標元素和一個 options 物件。
// create a new instance of `MutationObserver` named `observer`,
// passing it a callback function
const observer = new MutationObserver(() => {
console.log("callback that runs when observer is triggered");
});
// call `observe()`, passing it the element to observe, and the options object
observer.observe(document.querySelector("#element-to-observe"), {
subtree: true,
childList: true,
});
使用 subtree 時移除的後代節點
如果您使用 subtree 選項監視一個節點,即使該子樹的一部分已被移除,您仍將收到該節點後代節點的更改通知。但是,一旦關於移除的通知被傳遞,該已分離子樹的進一步更改將不再觸發觀察者。
這可以防止您錯過在連線斷開後、您有機會專門開始監視已移動節點或子樹以進行更改之前發生的更改。理論上,這意味著如果您跟蹤描述發生的更改的 MutationRecord 物件,您應該能夠“撤銷”更改,將 DOM 恢復到其初始狀態。
<div id="target">
<div id="child"></div>
</div>
const target = document.getElementById("target");
const child = document.getElementById("child");
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
console.log(mutation.type, mutation.target.id, mutation.attributeName);
if (mutation.type === "childList" && mutation.target.id === "target") {
// After receiving the notification that the child was removed,
// further modifications to the detached subtree no longer trigger the observer.
child.setAttribute("data-bar", "");
}
});
});
observer.observe(target, {
attributes: true,
childList: true,
subtree: true,
});
target.removeChild(child);
// This change happens before the "childList target" notification is delivered,
// so it will also trigger the observer.
child.setAttribute("data-foo", "");
// Output:
// childList target null
// attributes child data-foo
// There is no "attributes child data-bar" notification.
使用 attributeFilter
在此示例中,設定了一個 Mutation Observer 來監視顯示聊天室使用者名稱稱的子樹中任何元素的 status 和 username 屬性的更改。例如,這可以讓程式碼反映使用者暱稱的更改,或將其標記為離開鍵盤 (AFK) 或離線。
function callback(mutationList) {
mutationList.forEach((mutation) => {
switch (mutation.type) {
case "attributes":
switch (mutation.attributeName) {
case "status":
userStatusChanged(mutation.target.username, mutation.target.status);
break;
case "username":
usernameChanged(mutation.oldValue, mutation.target.username);
break;
}
break;
}
});
}
const userListElement = document.querySelector("#user-list");
const observer = new MutationObserver(callback);
observer.observe(userListElement, {
attributeFilter: ["status", "username"],
attributeOldValue: true,
subtree: true,
});
監視屬性值
在此示例中,我們監視一個元素以獲取屬性值更改,並新增一個按鈕,在元素的 dir 屬性("ltr" 和 "rtl")之間進行切換。在觀察者的回撥函式中,我們記錄了屬性的舊值。
HTML
<button id="toggle">Toggle direction</button><br />
<div id="container">
<input type="text" id="rhubarb" dir="ltr" value="Tofu" />
</div>
<pre id="output"></pre>
CSS
body {
background-color: paleturquoise;
}
button,
input,
pre {
margin: 0.5rem;
}
JavaScript
const toggle = document.querySelector("#toggle");
const rhubarb = document.querySelector("#rhubarb");
const observerTarget = document.querySelector("#container");
const output = document.querySelector("#output");
toggle.addEventListener("click", () => {
rhubarb.dir = rhubarb.dir === "ltr" ? "rtl" : "ltr";
});
const config = {
subtree: true,
attributeOldValue: true,
};
const callback = (mutationList) => {
for (const mutation of mutationList) {
if (mutation.type === "attributes") {
output.textContent = `The ${mutation.attributeName} attribute was modified from "${mutation.oldValue}".`;
}
}
};
const observer = new MutationObserver(callback);
observer.observe(observerTarget, config);
結果
規範
| 規範 |
|---|
| DOM # ref-for-dom-mutationobserver-observe② |
瀏覽器相容性
載入中…