JavaScript で DOM 要素を監視する MutationObServer の詳細

JavaScript で DOM 要素を監視する MutationObServer の詳細

1. 基本的な使い方

これは MutationObserver コンストラクターを通じてインスタンス化でき、パラメーターはコールバック関数です。

オブザーバーを新しい MutationObserver(() => console.log("change"));

console.log(オブザーバー);

オブザーバー オブジェクトのプロトタイプ チェーンは次のとおりです。

MutationObserverインスタンス:

disconnectobservertakeRecordsメソッドがあることがわかります。

1. オブザーバー方式による監視

observerメソッドは、 DOM要素を関連付け、関連する設定に従ってリッスンするために使用されます。

構文は次のとおりです。

// 2 つのパラメータ observer (DOM 要素、MutationObserverInit オブジェクト) を受け取ります。

で:

  • 最初のパラメータ DOM 要素は、body、div などのページ要素です。
  • 2 番目のパラメータは、監視する範囲を設定することです。たとえば、属性、テキスト、子ノードなどは、キーと値のペアの配列です。

例 1: body 要素クラスの変更を監視する:

オブザーバーを新しい MutationObserver(() => console.log("change"));

//body要素の属性の変更を監視する observer.observe(document.body, {

    属性: true

});

// body 要素のクラスを変更すると、MutationObserver オブジェクトの作成時に渡されたコールバック関数が非同期的に実行されます。 document.body.className = "main";

console.log("body属性が変更されました");

// コンソール出力:

// ボディ属性を変更しました // 変更

上記changeの出力はbody属性を変更した後のものです。登録したコールバック関数が非同期で実行され、後から実行されることがわかります。

2. コールバック関数にMutationRecordインスタンス配列パラメータを追加する

現在、コールバック関数は非常に単純で、文字列を出力するだけなので、どのような変更が行われたかは不明です。

実際、コールバック関数はMutationRecordインスタンスの配列を受け取り、これを使用して実際に詳細情報を表示できます。

オブザーバー = 新しい MutationObserver(

    // コールバック関数は MutationRecord インスタンスの配列です。形式は次のとおりです。

    // [MutationRecord、MutationRecord、MutationRecord、...]

    (mutationRecords) => console.log(mutationRecords)

);

オブザーバー.観察(ドキュメント.本文, {

    属性: true

});

ドキュメント.body.className = "main";

console.log("body属性が変更されました");

// コンソール出力:

// ボディ属性を変更しました // (1) [MutationRecord]

mutationRecords情報は次のとおりです。

MutationRecordの例:

より重要な情報の一部:

  • attributeName変更する属性の名前を示します
  • targetを変更する
  • type

本文の属性を複数回変更すると、複数のレコードが作成されます。

// ミューテーションレコード

オブザーバー = 新しい MutationObserver(

    // コールバック関数は配列である MutationRecord インスタンスを受け取ります。

    (mutationRecords) => console.log(mutationRecords)

);

オブザーバー.観察(ドキュメント.本文, {

    属性: true

});

 

// 3 回変更します document.body.className = "main";

document.body.className = "コンテナ";

document.body.className = "ボックス";

 

// コンソールに次のように出力されます:

// (3) [ミューテーションレコード、ミューテーションレコード、ミューテーションレコード]

知らせ:

ここでは、コールバックは変更ごとに 1 回実行されるわけではありません。代わりに、変更が行われるたびに MutationRecord インスタンスが mutationRecords パラメータに追加され、最後にコールバックが実行されて出力されます。

変更ごとにコールバックが 1 回実行されると、パフォーマンスが低下します。

3. Disconnectメソッドはコールバックを終了する

コールバックを終了する場合は、disconnect メソッドを使用できます。

オブザーバー = 新しい MutationObserver(

    (mutationRecords) => console.log(mutationRecords)

);

オブザーバー.観察(ドキュメント.本文, {

    属性: true

});

// 最初の変更 document.body.className = "main";

 

//observer.disconnect() を終了します。

 

// 2 番目の変更 document.body.className = "container";

 

// ログ出力なし

コールバック関数は非同期で実行され、最後に実行されるため、最初の変更を含め、ここではログ出力はありません。 observerは後で終了されるため、実行されません。

setTimeout を使用して最終終了を制御し、コールバックが正常に実行されるようにすることができます。

オブザーバー = 新しい MutationObserver(

    (mutationRecords) => console.log(mutationRecords)

);

オブザーバー.観察(ドキュメント.本文, {

    属性: true

});

// 最初の変更 document.body.className = "main";

 

// 終了 setTimeout(() => {

    オブザーバーを切断します。

    // 3 番目の変更、次の変更はコールバックされません document.body.className = "container";

}, 0);

 

// 2 番目の変更 document.body.className = "container";

 

// ページ出力:

// (2) [ミューテーションレコード、ミューテーションレコード]

終了後に再アクティブ化

終了後、再起動することができます。次の例を参照してください。

オブザーバー = 新しい MutationObserver(

    (mutationRecords) => console.log(mutationRecords)

);

オブザーバー.観察(ドキュメント.本文, {

    属性: true

});

// 最初の変更は、mutationRecords 配列に入力されます。document.body.className = "main";

// 終了 setTimeout(() => {

    オブザーバーを切断します。

    // 2 番目の変更は終了しているため、次の変更は mutationRecords 配列に入力されません。 document.body.className = "container";

}, 0);

タイムアウトを設定する(() => {

    // オブザーバーを再度有効にします。observe(document.body, {

        属性: true

    });

    // 本文の属性を変更し、mutationRecords 配列を入力します。document.body.className = "container";

}, 0);

 

// コンソール出力:

// [ミューテーションレコード]

// [ミューテーションレコード]

ここでのコールバック関数は 2 回実行され、2 つの値を出力します。

  • 最初の出力は最初の変更です。その後に同期コードがないため、コールバックが実行されます。
  • 2 番目の出力は 3 番目の変更です。再度有効になっているため、コールバックは正常に実行されます。

2 番目の変更では、 observerが終了するため、変更されたbody属性はmutationRecords配列に含まれません。

4. takeRecordsメソッドは変更されたレコードを取得します

observerを終了する前に既存のmutationRecordsを処理する場合は、 takeRecordsメソッドを使用してそれらを取得できます。

オブザーバー = 新しい MutationObserver(

    (mutationRecords) => console.log(mutationRecords)

);

オブザーバー.観察(ドキュメント.本文, {

    属性: true

});

 

// 最初の変更は、mutationRecords 配列に入力されます。document.body.className = "main";

// 2 番目の変更は、mutationRecords 配列に入力されます。document.body.className = "container";

// 3 番目の変更は、mutationRecords 配列に入力されます。document.body.className = "box";

// 変更レコードを取得して処理します let mutationRecords = observer.takeRecords();

コンソールにログを記録します。

// コンソール出力:

// (3) [ミューテーションレコード、ミューテーションレコード、ミューテーションレコード]

コンソールにログを記録します。

// コンソール出力:

// []

//observer.disconnect() を終了します。

2. 複数の要素を聴く

上記の監視には1つの要素しかありません。複数の要素を監視したい場合は、 MutationObserverインスタンスを再利用できます。

オブザーバー = 新しい MutationObserver(

    (mutationRecords) => console.log(mutationRecords)

);

// div1 要素を作成して listen します。let div1 = document.createElement("div");

オブザーバー.観察(div1, {

    属性: true

});

div1.id = "ボックス1";

 

// div2 を作成して listen します。let div2 = document.createElement("div");

オブザーバー.観察(div2, {

    属性: true

});

div2.id = "ボックス2";

 

// コンソール出力:

// (2) [ミューテーションレコード、ミューテーションレコード]

コンソールには次の 2 つの MutationRecord が出力されます。

  • 最初のMutationRecordは、div1 の id 属性の変更レコードです。
  • 2 番目のMutationRecordは、div2 の id 属性の変更レコードです。

その他の使用方法は上記と同様です。

3. 監視スコープMutationObserverInitオブジェクト

上記の監視は属性を監視するためのものですが、もちろん、テキスト、子ノードなど、他のものも監視できます。

1. プロパティを観察する

上記の例はすべて、要素自体の属性を観察します。次に、カスタム属性の別の例を示します。

オブザーバー = 新しい MutationObserver(

    (mutationRecords) => console.log(mutationRecords)

);

オブザーバー.観察(ドキュメント.本文, {

    属性: true

});

// カスタム属性を変更する document.body.setAttribute("data-id", 1);

 

// コンソール出力:

// [ミューテーションレコード]

カスタム属性の変更も、 mutationRecords配列に追加されます。

また、 data-idデータなどを持つ要素をマークするためによく使用されることも言及する価値があります。変更があった場合、プログラムはそれを監視し、対応するロジックを処理できます。

attributeFilter フィルタリング:

指定した属性の変更を監視する場合は、 attributeFilterを使用してフィルタリングできます。

オブザーバー = 新しい MutationObserver(

    (mutationRecords) => console.log(mutationRecords)

);

オブザーバー.観察(ドキュメント.本文, {

    属性: true、

    // ホワイトリスト属性を設定するFilter: ["data-id"]

});

 

// ホワイトリスト attributeFilter の属性を変更し、mutationRecords を入力します

document.body.setAttribute("データID", 1);

 

// ホワイトリスト attributeFilter に含まれず、mutationRecords に入力されない属性を変更します

document.body.setAttribute("class", "main");

 

// コンソール出力:

// [ミューテーションレコード]

attributeOldValue は古い値を記録します:

古い値を記録する場合は、 attributeOldValue trueに設定できます。

オブザーバー = 新しい MutationObserver(

    // MutationRecord オブジェクトの oldValue は古い値を表します (mutationRecords) => console.log(mutationRecords.map((x) => x.oldValue))

);

オブザーバー.観察(ドキュメント.本文, {

    属性: true、

    属性OldValue: true、

});

// 最初の変更。元々値がないので、古い値 oldValue = null

document.body.setAttribute("class", "main");

// 2回目の変更。以前に一度変更されているため、古い値 oldValue = main

document.body.setAttribute("クラス", "コンテナ");

 

// コンソール出力:

// (2) [null, 'main']

2. テキストを観察する

テキストを観察するには、 characterData trueに設定しますが、観察できるのはテキスト ノードのみです。

次の例を考えてみましょう。

<!-- セクシーな div -->

<div id="box">こんにちは</div>

<script type="text/javascript">

    オブザーバー = 新しい MutationObserver(

        (mutationRecords) => console.log(mutationRecords)

    );

    // テキストノードを取得します。let textNode = document.getElementById("box").childNodes[0];

    オブザーバー.observe(textNode, {

        //テキストの変更を観察する characterData: true

    });

    // テキストを変更します textNode.textContent = "Hi";

 

    // コンソール出力:

    // [ミューテーションレコード]

</スクリプト>

div 要素を直接リッスンすると機能しません。

<!-- セクシーな div -->

<div id="box">こんにちは</div>

<script type="text/javascript">

    オブザーバー = 新しい MutationObserver(

        (mutationRecords) => console.log(mutationRecords)

    );

    // div をリッスンしても効果はありません let box = document.getElementById("box");

    オブザーバー.観察(ボックス, {

        文字データ: true

    });

    box.textContent = "こんにちは";

 

    //コンソールに出力なし</script>

characterDataOldValue は古い値を記録します。

テキストの古い値を記録する場合は、 characterDataOldValue trueに設定できます。

<!-- セクシーな div -->

<div id="box">こんにちは</div>

 

<script type="text/javascript">

    オブザーバー = 新しい MutationObserver(

        (mutationRecords) => console.log(mutationRecords.map((x) => x.oldValue))

    );

    // テキストノードを取得します。let textNode = document.getElementById("box").childNodes[0];

    オブザーバー.observe(textNode, {

        //テキストの変更を監視 characterData: true,

        // 古いデータを保持する characterDataOldValue: true,

    });

    // テキストを 2 回変更します textNode.textContent = "Hi";

    textNode.textContent = "いいですね";

 

    // コンソール出力:

    // (2) ['こんにちは', 'やあ']

</スクリプト>

div 内の元のコンテンツは Hello でしたが、最初に Hi に変更され、次に Nice に変更されたため、 2 回の変更後の古い値は Hello と Hi になります。

3. 子ノードを観察する

MutationObserverインスタンスは、ターゲット ノードの子ノードの変更も監視できます。

<!-- セクシーな div -->

<div id="box">こんにちは</div>

<script type="text/javascript">

    オブザーバー = 新しい MutationObserver(

        (mutationRecords) => console.log(mutationRecords)

    );

    // div を取得する

    box = document.getElementById("box"); とします。

    オブザーバー.観察(ボックス, {

        //子ノードの変更を観察 childList: true,

    });

    // 要素を追加 let span = document.createElement("span")

    span.textContent = "世界";

    ボックスの子要素を追加します。

 

    // コンソール出力:

    // [ミューテーションレコード]

</スクリプト>

MutationRecordaddedNodes属性は追加されたノードを記録します。

ノードを削除するには:

<!-- セクシーな div -->

<div id="box">こんにちは</div>

 

<script type="text/javascript">

    オブザーバー = 新しい MutationObserver(

        (mutationRecords) => console.log(mutationRecords)

    );

 

    // div を取得する

    box = document.getElementById("box"); とします。

    オブザーバー.観察(ボックス, {

        //子ノードの変更を観察 childList: true,

    });

    // 最初の子ノード(Hello テキスト ノード)を削除します。box.removeChild(box.childNodes[0]);

 

    // コンソール出力:

    // [ミューテーションレコード]

</スクリプト>

MutationRecordremovedNodesプロパティは、削除されたノードを記録します。

モバイルノード:

既存のノードを移動すると、まずノードを削除してから追加するため、2 つのMutationRecordレコードが記録されます。

<!-- セクシーな div -->

<div id="box">こんにちは世界</span></div>

 

<script type="text/javascript">

    オブザーバー = 新しい MutationObserver(

        (mutationRecords) => console.log(mutationRecords)

    );

 

    // div を取得する

    box = document.getElementById("box"); とします。

    オブザーバー.観察(ボックス, {

        //子ノードの変更を観察 childList: true,

    });

    // spanノードをHelloノードの先頭に移動します。box.insertBefore(box.childNodes[1], box.childNodes[0]);

    // ノードを移動するということは、実際には最初にノードを削除してから追加することを意味します。

 

    // コンソール出力:

    // (2) [ミューテーションレコード、ミューテーションレコード]

</スクリプト>

4. サブツリーを観察する

上記で観察されたノードはすべて、現在設定されているターゲット ノードです。たとえば、 bodyの場合、 body要素とその子ノードの変更のみを観察できます。

bodyとそのすべての子孫ノードの変更を監視する場合は、 subtreeプロパティをtrueに設定できます。

<!-- セクシーな div -->

<div id="box">こんにちは世界</span></div>

 

<script type="text/javascript">

    オブザーバー = 新しい MutationObserver(

        (mutationRecords) => console.log(mutationRecords)

    );

 

    box = document.getElementById("box"); とします。

    オブザーバー.観察(ボックス, {

        属性: true、

        //サブツリーの変更を観察する subtree: true

    });

    // span要素のid属性の変更を観察できます box.childNodes[1].id = "text";

    // コンソール出力:

    // [ミューテーションレコード]

</スクリプト>

subtree trueに設定すると、 div 要素自体だけでなくspan要素も監視できるようになります。

要約:

  • 1. MutationObserverインスタンスを使用してオブジェクトを観察できます。
  • 2. MutationRecordインスタンスはすべての変更を記録します。
  • 3. コールバック関数は、すべてのスクリプト タスクが完了した後にのみ実行されます。つまり、非同期メソッドを使用します。
  • 4. 観測可能なアクセスは、属性、テキスト、子ノード、サブツリーです。

これで、 JavaScriptで DOM 要素を監視するMutationObServerの詳細に関するこの記事は終了です。JavaScript で DOM 要素を監視する MutationObServer に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • JavaScriptはDOM要素のサイズ変更を監視します
  • JavaScript で DOM 要素を監視する MutationObServer の詳細
  • Javascript DOM、ノード、要素取得の紹介
  • JavaScript WebAPI、DOM、イベント、操作要素例の詳しい説明

<<:  FlashFXP FTP クライアント ソフトウェア登録クラッキング方法

>>:  オブジェクトアニメーションによってブロックされずにオブジェクトに div を表示する方法

推薦する

CSS における zoom:1 属性の定義と機能

今日、CSS の zoom 属性は何のために使用されるのかと尋ねられました。この属性は、フローティン...

Vueの学習手順

目次1. v-text (v-instruction name = "variable&q...

MySQL マスタースレーブレプリケーションの役割と動作原理の詳細な説明

1. マスタースレーブレプリケーションとは何ですか?マスタースレーブレプリケーションは、スレーブデー...

CSS変数がJSインタラクティブコンポーネント開発にもたらす改善と変更のサンプルコードの詳細な説明

1. CSS変数がもたらす質的変化CSS 変数によってもたらされる改善は、CSS コードの節約や C...

サーバー上で selenium+chromedriver を実行するための詳細なチュートリアル

1. はじめにSelenium を使用して Web サイトからデータをスクレイピングしたいのですが、...

CSS ピックアップ矢印、カタログ、アイコン実装コード

1. CSS その他のアイコンアイコンを作成するには 3 つの方法があります。写真css (小さな矢...

Dockerでmongodbデータベースを使用するための実装コード

mongoイメージを取得する sudo docker pull mongo mongodbサービスを...

Dockerコマンドは一般ユーザーが実行できるように実装されている

dockerをインストールすると、通常はdockerユーザーグループが作成されます。ステップ2: 現...

Nginx の高同時実行最適化の実践

1. チューニングの必要性​ 私は、どのように書けばいいのか本当に分からないので、共有するために最適...

Linux touch コマンドの使用例

Linux touch コマンドの詳細な説明: 1. コマンド機能:ファイルまたはディレクトリの作成...

HTMLフォーム要素の包括的な理解

以下のように表示されます。 XML/HTML コードコンテンツをクリップボードにコピー<!DO...

CentOS のファイルと権限の基本操作チュートリアル

序文始める前に、ファイル属性とファイル属性を変更する方法について簡単に理解しておく必要があります。 ...

一般的な HBase 運用および保守ツール 10 個の概要

概要: HBase には、ユーザーに管理、分析、修復、デバッグ機能を提供するための多くの操作および保...

Docker可視化ツールPortainerの導入と中国語翻訳

#docker 検索#docker プルポーター1. イメージを取得した後、中国語パッケージをダウン...