Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
181
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

@munieru_jp

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

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)
  }
})()

参考リンク

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
181
Help us understand the problem. What are the problem?