MutationObserver で DOM 変更を監視する
Google 翻訳の Chrome 拡張機能がどうやって動いているのかなーとソースを追っていたら、MutationObserver
なる API を発見した。
どうもコレで DOM の変更を監視できるようだ。
早速試してみた。以下のデモページにアクセスしたら開発者ツールを表示し、「Append」ボタンや「Remove」ボタンを押してみよう。「PROCESS」というコンソール出力が確認できるはずだ。
// DOM 変更を検知した時に実行したい関数を定義しておく
const myCallbackFunc = (mutations) => {
console.log('DOM 変更があった', mutations);
};
// コールバック関数を指定してインスタンスを作る
const observer = new MutationObserver(myCallbackFunc);
// body 要素配下の DOM 変更の監視を開始する
observer.observe(document.body, {
childList : true, // 対象ノードの子ノード(テキストノードも含む)に対する追加・削除を監視する
attributes : true, // 対象ノードの属性に対する変更を監視する
characterData: true, // 対象ノードのデータに対する変更を監視する
subtree : true // 対象ノードとその子孫ノードに対する変更を監視する
});
// 監視を停止する場合は以下を呼ぶ
observer.disconnect();
new MutationObserver()
のコンストラクタ引数に、コールバック関数を渡す。仮引数 mutations
が受け取れる。
mutationObserver.observe()
で監視を開始する際、監視したい親要素を指定できる。今回は document.body
で body
配下全体を監視したが、任意の Element を指定できる。
第2引数で色々とオプションを渡しているが、子要素を監視するか否か、とか、属性の変更も見るかどうか、とかが指定できる。今回はあらゆる変更を検知するようオプションを指定しておいた。
あとは body
要素の配下で、appendChild()
だったり、innerHTML
の書き換えだったりが発生すると、この MutationObserver が反応してコールバック関数を実行してくれる、というワケ。
テキストボックス (input
要素) や、テキストボックスの入力は監視できなかったので注意。コチラは素直に addEventListener('input')
を使うかな。
はて、そうすると DOM 要素の変更を監視して何がしたいか、というと、あんまり使用頻度は多くない気がする。何に使おうか、考えてみる。