LoginSignup
230
202

More than 3 years have passed since last update.

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

Last updated at Posted at 2017-10-23

JavaScriptのMutationObserverを用いて、ウェブページにおけるDOMの変化を監視する方法を紹介します。

基本的な流れ

どの変化を監視する場合も、基本的には次のような流れとなります。

監視ターゲットの取得

const target = document.getElementById('target-id')

オブザーバーの作成

const observer = new MutationObserver(records => {
  // 変化が発生したときの処理を記述
})

監視の開始

observer.observe(target, {
  // オプションを指定
})

(必要に応じて)監視の停止

observer.disconnect()

属性の変化を監視

属性の変化を監視するには、オプションのattributestrueにします。

// 監視ターゲットの取得
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']
})

文字データの変化を監視

文字データの変化を監視するには、オプションのcharacterDatatrueにします。

// 監視ターゲットの取得
const target = document.getElementById('target-id')

// オブザーバーの作成
const observer = new MutationObserver(records => {
  // 変化が発生したときの処理を記述
})

// 監視の開始
observer.observe(target, {
  characterData: true
})

子要素リストの変化を監視

子要素リストの変化を監視するには、オプションのchildListtrueにします。

// 監視ターゲットの取得
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)
  }
})()

参考リンク

230
202
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
230
202