このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docsコミュニティーについてもっと知り、仲間になるにはこちらから。
MutationObserver: observe() メソッド
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since 2015年7月.
MutationObserver のobserve() メソッドは、MutationObserver コールバックを設定し、与えられたオプションに適合する DOM への変更の通知の受信を開始します。
設定によっては、オブザーバーは DOM ツリー内の単一のノード (Node) を監視したり、そのノードとその子孫ノードの一部またはすべてを監視したりします。同じノードは複数のオブザーバーによって監視することができ、同じMutationObserver を複数回observe() を呼び出すことで、DOMツリーのさまざまな部分の変更や、さまざまな型の変更を監視することができます。
MutationObserver を停止するには、MutationObserver.disconnect() を呼び出してください。(これにより、そのコールバックはそれ以降発生しなくなります。)
In this article
構文
observe(target, options)引数
targetDOM ツリー内で変更を監視したり、監視するノードのサブツリーのルートになったりする DOM ノード (
Node)(あるいは要素 (Element) である可能性もあります)。optionsどの DOM の変更を
mutationObserverのcallbackに報告するかを記述するオプションを提供するオブジェクト。observe()を呼ぶ際には、childList、attribute、characterDataのうちの少なくとも 1 つはtrueでなければなりません。そうでない場合は、TypeError例外が発生します。オプションは次の通りです。
subtree省略可trueに設定すると、targetを基点とするノードのサブツリー全体に監視が拡張されます。他のプロパティはすべて、targetノードだけに適用されるのではなく、サブツリーのすべてのノードに拡張されます。既定値はfalseです。targetの子孫が除去された場合、その子孫のサブツリーに対する変更は、その除去に関する通知が配信されるまで、引き続き監視されます。childList省略可trueに設定すると、対象とするノード(およびsubtreeがtrueの場合はその子孫)に新しい子ノードが追加されたり、既存の子ノードが除去されたりしたかどうかを監視します。既定値はfalseです。attributes省略可trueに設定すると、監視対象のノードまたはノードの属性値の変更を監視します。attributeFilterまたはattributeOldValueのいずれかを指定した場合は、既定値はtrueです。それ以外の場合、既定値はfalseです。attributeFilter省略可監視対象とする具体的な属性名の配列です。このプロパティが含まれていない場合、すべての属性に対する変更が変更通知を発生させます。
attributeOldValue省略可trueに設定すると、ノードまたはノードの属性変更を監視している際に変更される属性の値を前回記録した値で置き換えます。属性の変更を監視し、値を記録する例については、属性値の監視を参照してください。既定値はfalseです。characterData省略可trueに設定すると、指定したターゲットノード(およびsubtreeがtrueの場合はその子孫)を監視し、そのノードまたはノード群に格納されている文字データに変更があったかどうかを確認します。既定では、characterDataOldValueを指定した場合はtrue、指定しない場合はfalseです。characterDataOldValue省略可trueに設定すると、監視対象のノードのテキストが変更されるたびに、そのノードのテキストの前回値が記録されます。既定値はfalseです。
返値
なし (undefined)。
例外
TypeError以下のいずれかの状況で発生します。
optionsが、実際には何も監視しないように設定されている場合。(例えば、childList、attributes、characterDataがすべてfalseの場合。)options.attributesの値がfalse(これは属性の変更を監視しないことを示す)であるにもかかわらず、attributeOldValueはtrueであるか、または、attributeFilterが存在する場合。characterDataOldValueはtrueであるにもかかわらず、characterDataがfalse(これは、文字の変更を監視しないことを示す)である場合。
例
>基本的な使い方
この例では、observe() をMutationObserver のインスタンスに対して呼び出し、設定した後、ターゲット要素とオプションオブジェクトを渡すとどうなるかを示します。
// `MutationObserver` の新しいインスタンスを `observer` という名前で作成し、// コールバック関数を渡すconst observer = new MutationObserver(() => { console.log("オブザーバーが検出を行ったときに実行されるコールバック");});// `observe()` を呼び出し、監視する要素とオプションオブジェクトを渡すobserver.observe(document.querySelector("#element-to-observe"), { subtree: true, childList: true,});subtree を使用する際に子孫を除去
subtree オプションを使用してノードを監視している場合、そのサブツリーの一部が除去された後でも、そのノードの子孫に対する変更の通知を受け続けることができます。 ただし、除去に関する通知が配信された後は、切り離されたサブツリーに対するそれ以上の変更は、オブザーバーが検出を行わなくなります。
これにより、接続が切断された後、移されたノードまたはサブツリーの詳細な変更監視を開始する前に発生する変更を見逃すことを防ぎます。理論的には、発生した変更を記述するMutationRecord オブジェクトを追跡していれば、変更を「元に戻す」ことができ、DOM を初期状態に巻き戻すことができるはずです。
<div> <div></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") { // 子要素が除去されたという通知を受け取った後、切り離されたサブツリーに対する // さらなる変更については、オブザーバーが検出を行わなくなる child.setAttribute("data-bar", ""); } });});observer.observe(target, { attributes: true, childList: true, subtree: true,});target.removeChild(child);// この変更は "childList" を対象とする通知が配信される前に発生するため、// これもオブザーバーが検出します。child.setAttribute("data-foo", "");// 出力:// childList target null// attributes child data-foo// "attributes child data-bar" の通知はありません。attributeFilter の使用
この例では、変更オブザーバーを設定し、チャットルームのユーザーの名前を表示するサブツリー内の要素の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("#userlist");const observer = new MutationObserver(callback);observer.observe(userListElement, { attributeFilter: ["status", "username"], attributeOldValue: true, subtree: true,});属性値の監視
この例では、属性値の変更を監視する要素を観察し、その要素のdir 属性を"ltr" と"rtl" との間で切り替えるボタンを追加します。オブザーバーのコールバックの中で、属性の古い値をログ出力します。
HTML
<button>方向を切り替え</button><br /><div> <input type="text" dir="ltr" value="Tofu" /></div><pre></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 = `${mutation.attributeName} 属性は "${mutation.oldValue}" から変化しました。`; } }};const observer = new MutationObserver(callback);observer.observe(observerTarget, config);結果
仕様書
| Specification |
|---|
| DOM> # ref-for-dom-mutationobserver-observe②> |