【JavaScript】MutationObserverでDOM変化を監視する方法

JavaScript

Webアプリや動的なページでは、JavaScriptや外部ライブラリによってDOMが書き換えられることがよくあります。要素が追加されたり属性が変化したときに自動で処理を実行したい場合、MutationObserverを使うと効率的にDOMの変化を監視できます。ここではMutationObserverの基本から実用例まで解説します。

MutationObserverとは

MutationObserverはDOMの変更を監視し、変化があったときにコールバックを実行できるAPIです。従来はDOMSubtreeModifiedなどのイベントを使っていましたが、非推奨となり、現在はMutationObserverが標準的な方法となっています。

基本構文

// 監視対象の要素を取得
const target = document.getElementById('content');

// コールバック関数を定義
const callback = (mutationsList, observer) => {
  for (const mutation of mutationsList) {
    if (mutation.type === 'childList') {
      console.log('子要素の追加・削除が検出されました');
    }
    if (mutation.type === 'attributes') {
      console.log('属性の変更が検出されました:', mutation.attributeName);
    }
  }
};

// オブザーバーを作成
const observer = new MutationObserver(callback);

// オプションを指定して監視開始
observer.observe(target, {
  childList: true,
  attributes: true,
  subtree: true
});

監視オプション

observeの第2引数で監視対象を細かく制御できます。

  • childList:子要素の追加・削除を監視
  • attributes:属性の変更を監視
  • characterData:テキストノードの変更を監視
  • subtree:子孫ノードまで監視対象に含める
  • attributeFilter:特定の属性だけ監視

実用例:動的に追加された要素の処理

JavaScriptで動的に追加される要素に対してイベントを自動付与するケースです。

const list = document.getElementById('list');

const observer = new MutationObserver(mutations => {
  mutations.forEach(mutation => {
    if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
      mutation.addedNodes.forEach(node => {
        if (node.nodeType === 1 && node.matches('li')) {
          console.log('新しいリスト項目:', node.textContent);
        }
      });
    }
  });
});

observer.observe(list, { childList: true });

実用例:属性変化の監視

ボタンにdisabled属性が付与されたタイミングを監視する例です。

const button = document.querySelector('button');

const observer = new MutationObserver(mutations => {
  mutations.forEach(mutation => {
    if (mutation.type === 'attributes' && mutation.attributeName === 'disabled') {
      console.log('disabled属性が変更されました:', button.disabled);
    }
  });
});

observer.observe(button, { attributes: true });

監視の停止

不要になったときはdisconnectで監視を止めることができます。

observer.disconnect();

まとめ

MutationObserverを使うとDOMの変化を効率的に監視でき、子要素の追加や属性の変更に応じて柔軟に処理を実行できます。イベントバインドや動的UI更新に活用することで、より堅牢なフロントエンド開発が可能になります。