タグの追加や削除を監視する

JavaScriptでタグの追加や削除を検知するには、MutationObserverを使用します。

MutationObserverのコンストラクタは引数にタグの追加や削除が合った時に実行するコールバック関数を受け取ります。 

const observer = new MutationObserver(mutations => {
    // 変更があった時に実行する処理
});

コールバック関数は、第1引数にMutationRecordを受け取ります。

MutationRecordのaddedNodesプロパティは追加されたノード、
removedNodesプロパティは削除されたノードを返します。

const observer = new MutationObserver(mutations => {
    mutations.forEach(mutation => {
        mutation.addedNodes.forEach(node => {
            // nodeは追加されたノード
        });
        mutation.removedNodes.forEach(node => {
            // nodeは削除されたノード
        });
    });
});

監視を開始するときは、observe()メソッドを呼びます。

observe()メソッドは引数に、監視するノードと変更の種類を指定するMutationObserverInitオブジェクトを受け取ります。

  • MutationObserverInit
    • childList 対象ノードの子ノード(テキストノードも含む)に対する追加・削除を監視する場合は true にします。
    • attributes 対象ノードの属性に対する変更を監視する場合は true にします。
    • characterData 対象ノードのデータに対する変更を監視する場合は true にします。
    • subtree 対象ノードとその子孫ノードに対する変更を監視する場合は true にします。
    • attributeOldValue 対象ノードの変更前の属性値を記録する場合は true にします(attributes が true の時に有効)。
    • characterDataOldValue 対象ノードの変更前のデータを記録する場合は true にします(characterData が true の時に有効)。
    • attributeFilter すべての属性の変更を監視する必要がない場合は、(名前空間を除いた)属性ローカル名の配列を指定します。
/ 監視するノード
const container = document.getElementById("container");
// 監視を開始する
observer.observe(container, { childList: true, });

サンプルプログラム

次のサンプルプログラムは、追加ボタンを押すとノードを追加し、削除ボタンを押すとノードを削除します。

ノートが追加・削除されると、変更されたノードのテキストが表示されます。

<!DOCTYPE html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>タグの追加や削除を監視するサンプル</title>
</head>

<body>
    <h1>タグの追加や削除を監視するサンプル</h1>
    <button id="insertButton">追加</button>
    <button id="deleteButton">削除</button>
    <ul id="container"></ul>
    <hr>
    <ol id="record"></ol>

    <script>
        const container = document.getElementById("container");
        // 追加ボタン
        document.getElementById("insertButton").addEventListener("click", () => {
            const li = document.createElement("li");
            li.append(document.createTextNode(Date.now()));
            container.appendChild(li);
        });
        // 削除ボタン
        document.getElementById("deleteButton").addEventListener("click", () => {
            if (container.firstChild) {
                container.removeChild(container.firstChild);
            }
        });

        const record = document.getElementById("record");
        const observer = new MutationObserver(mutations => {
            mutations.forEach(mutation => {
                mutation.addedNodes.forEach(node => {
                    const li = document.createElement('li');
                    li.append(document.createTextNode(`[追加] ${node.textContent}`));
                    record.appendChild(li);
                });
                mutation.removedNodes.forEach(node => {
                    const li = document.createElement('li');
                    li.append(document.createTextNode(`[削除] ${node.textContent}`));
                    record.appendChild(li);
                });
            });
        });
        observer.observe(container, { childList: true, });
    </script>
</body>

</html>

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください