JavaScriptのMutationObserverを用いて、ウェブページにおけるDOMの変化を監視する方法を紹介します。
基本的な流れ
どの変化を監視する場合も、基本的には次のような流れとなります。
監視ターゲットの取得
const target = document.getElementById('target-id')
オブザーバーの作成
const observer = new MutationObserver(records => {
// 変化が発生したときの処理を記述
})
監視の開始
observer.observe(target, {
// オプションを指定
})
(必要に応じて)監視の停止
observer.disconnect()
属性の変化を監視
属性の変化を監視するには、オプションのattributes
をtrue
にします。
// 監視ターゲットの取得
const target = document.getElementById('target-id')
// オブザーバーの作成
const observer = new MutationObserver(records => {
// 変化が発生したときの処理を記述
})
// 監視の開始
observer.observe(target, {
attributes: true
})
特定属性の変化を監視
特定の属性の変化を監視するには、オプションのattributeFilter
に監視対象の属性を指定します。
// 監視ターゲットの取得
const target = document.getElementById('target-id')
// オブザーバーの作成
const observer = new MutationObserver(records => {
// 変化が発生したときの処理を記述
})
// 監視の開始
observer.observe(target, {
attributes: true,
attributeFilter: ['class', 'style']
})
文字データの変化を監視
文字データの変化を監視するには、オプションのcharacterData
をtrue
にします。
// 監視ターゲットの取得
const target = document.getElementById('target-id')
// オブザーバーの作成
const observer = new MutationObserver(records => {
// 変化が発生したときの処理を記述
})
// 監視の開始
observer.observe(target, {
characterData: true
})
子要素リストの変化を監視
子要素リストの変化を監視するには、オプションのchildList
をtrue
にします。
// 監視ターゲットの取得
const target = document.getElementById('target-id')
// オブザーバーの作成
const observer = new MutationObserver(records => {
// 変化が発生したときの処理を記述
})
// 監視の開始
observer.observe(target, {
childList: true
})
オプション
observe
メソッドの第二引数のオプションで、監視方法を細かく指定できます。
プロパティ | 型 | 指定 | 内容 |
---|---|---|---|
attributes | Boolean | いずれか必須 | 属性の変化を監視 |
characterData | Boolean | 文字データの変化を監視 | |
childList | Boolean | 子要素リストの変化を監視 | |
attributeOldValue | Boolean | 任意 | 変更前の属性を使用 |
characterDataOldValue | Boolean | 任意 | 変更前の文字データを使用 |
attributeFilter | String[] | 任意 | 監視対象とする属性名リスト |
subtree | Boolean | 任意 | 子孫ノードを監視対象に含める |
例
MutationObserverを用いて、Twitterのタイムライン上に新着ツイートバーが現れた際、自動的にクリックして表示するユーザースクリプトの例です。
Twitterの新着ツイートを自動表示.user.js
// ==UserScript==
// @name Twitterの新着ツイートを自動表示
// @namespace https://munieru.jp
// @version 0.1
// @description Twitterの新着ツイートを自動表示します。
// @author @munieru_jp
// @match https://twitter.com/
// @grant none
// ==/UserScript==
(function () {
'use strict'
const CLASS_NEW_TWEETS_BAR = 'new-tweets-bar'
// 監視ターゲットの取得
const timeline = document.getElementById('timeline')
const streamContainer = timeline.querySelector('.stream-container')
const streamItem = streamContainer.querySelector('.stream-item')
// オブザーバーの作成
const observer = new MutationObserver(records => {
records.forEach(record => {
Array.from(record.addedNodes)
.filter(node => isNewTweetsBarElement(node))
.forEach(newTweetsBar => newTweetsBar.click())
})
})
// 監視の開始
observer.observe(streamItem, {
childList: true
})
function isNewTweetsBarElement (element) {
return element.classList.contains(CLASS_NEW_TWEETS_BAR)
}
})()