JavaScript / jQuery DOM変更リスナーはありますか?


402

基本的に、内容がDIV変更されたときにスクリプトを実行させたい。スクリプトは独立しているため(Chrome拡張機能のコンテンツスクリプトとWebページスクリプト)、DOM状態の変化を簡単に観察する方法が必要です。ポーリングを設定できましたが、それはだらしのないようです。

回答:


488

長い間、DOM3ミューテーションイベントは利用可能な最善のソリューションでしたが、パフォーマンス上の理由から廃止されました。DOM4ミューテーションオブザーバーは、廃止予定のDOM3 ミューテーションイベントに代わるものです。現在、これらは最新のブラウザーMutationObserver(またはWebKitMutationObserver古いバージョンのChromeでベンダーがプレフィックスとして)実装されています

MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

var observer = new MutationObserver(function(mutations, observer) {
    // fired when a mutation occurs
    console.log(mutations, observer);
    // ...
});

// define what element should be observed by the observer
// and what types of mutations trigger the callback
observer.observe(document, {
  subtree: true,
  attributes: true
  //...
});

この例では、DOMの変更documentとそのサブツリー全体をリッスンし、要素の属性の変更と構造の変更をトリガーします。ドラフト仕様には、有効なミューテーションリスナープロパティの完全なリストがあります

childList

  • trueターゲットの子への突然変異が観察される場合に設定されます。

属性

  • trueターゲットの属性への変更を監視する場合に設定します。

characterData

  • trueターゲットのデータへの変異を観察する場合に設定します。

サブツリー

  • trueターゲットだけでなくターゲットの子孫への変異も観察する場合に設定します。

attributeOldValue

  • 設定しtrueた場合attributes、突然変異のニーズを記録する前の真のターゲット属性値に設定されています。

characterDataOldValue

  • 設定しtrueた場合characterData、突然変異のニーズを記録する前に、真とターゲットのデータに設定されています。

attributeFilter

  • すべての属性の変更を監視する必要がない場合は、属性のローカル名(名前空間なし)のリストに設定します。

(このリストは2014年4月現在のものです。仕様の変更を確認できます。)


3
@AshrafBashir Firefox 19.0.2でサンプルが正常に機能しているのがわかり([{}])ます。コンソールにログが記録されているのがわかりますMutationRecord。これをクリックすると、期待どおりに表示されます。JSFiddleの一時的な技術的な失敗であった可能性があるため、もう一度確認してください。ミューテーションイベントをサポートする現在唯一のバージョンであるIE 10を使用していないため、IEではまだテストしていません。
アプシラー2013年

1
IE10 +で動作する回答を投稿したところです。
naugtur 2014年

1
仕様には、ミューテーションオブザーバーオプションを一覧表示する緑色のボックスがないようです。それはありませんリストにオプションのセクション5.3.1でをし、さらにその下にそれらを少しだけを説明しています。
LS

2
@LSおかげで、リンクを更新し、緑色のボックスのビットを削除し、リスト全体を私の回答に編集しました(将来のリンクの腐敗に備えて)。
アプシラー2014


211

編集する

この回答は廃止されました。アプシラーによる回答をご覧ください。

これはChrome拡張機能用であるため、標準のDOMイベント-を使用することもできますDOMSubtreeModified。ブラウザー間でのこのイベントのサポートを参照してください。1.0以降、Chromeでサポートされています。

$("#someDiv").bind("DOMSubtreeModified", function() {
    alert("tree changed");
});

こちらで実際の例をご覧ください


このイベントは、特定のセレクタの後でも発生する可能性があることに気付きました。現在調査中です。
Peder Rice

9
w3.org/TR/DOM-Level-3-Events/#event-type-DOMSubtreeModifiedによると、このイベントは廃止予定です。代わりに何を使用しますか?
Maslow、2012年


4
基本的にjqueryユーザーのためにそれを解決するgithub.com/joelpurra/jquery-mutation-summaryがあります。
Capi Etheriel 2012年

1
Chrome拡張機能を構築している場合でも機能します。貴重な。
concept47

49

多くのサイトはコンテンツを動的に追加/表示/変更するためにAJAXを使用しています。サイト内ナビゲーションの代わりに使用されることもあり、現在のURLはプログラムによって変更され、ページがリモートサーバーから完全に取得されないため、この場合、コンテンツスクリプトはブラウザーによって自動的に実行されません。


コンテンツスクリプトで使用可能なページ変更を検出する通常のJSメソッド。


拡張機能固有:バックグラウンド / イベントページでURLの変更を検出します。

ナビゲーションを操作する高度なAPIがあります:webNavigationwebRequest ですが、コンテンツスクリプトにメッセージ送信する単純なchrome.tabs.onUpdatedイベントリスナーを使用します。

  • manifest.jsonを:
    宣言の背景/イベントページ
    DECLARE コンテンツスクリプトの
    追加"tabs" 許可

  • background.js

    var rxLookfor = /^https?:\/\/(www\.)?google\.(com|\w\w(\.\w\w)?)\/.*?[?#&]q=/;
    chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
        if (rxLookfor.test(changeInfo.url)) {
            chrome.tabs.sendMessage(tabId, 'url-update');
        }
    });
  • content.js

    chrome.runtime.onMessage.addListener(function(msg, sender, sendResponse) {
        if (msg === 'url-update') {
            doSomething();
        }
    });

29

divを変更する方法に応じた別のアプローチ。JQueryを使用してhtml()メソッドでdivのコンテンツを変更する場合、そのメソッドを拡張し、htmlをdivに入れるたびに登録関数を呼び出すことができます。

(function( $, oldHtmlMethod ){
    // Override the core html method in the jQuery object.
    $.fn.html = function(){
        // Execute the original HTML method using the
        // augmented arguments collection.

        var results = oldHtmlMethod.apply( this, arguments );
        com.invisibility.elements.findAndRegisterElements(this);
        return results;

    };
})( jQuery, jQuery.fn.html );

html()の呼び出しをインターセプトし、これを使用して登録関数を呼び出します。これは、コンテキストで新しいコンテンツを取得するターゲット要素を参照してから、元のjquery.html()関数の呼び出しを渡します。JQueryはメソッドチェーニングに期待しているため、元のhtml()メソッドの結果を返すことを忘れないでください。

メソッドのオーバーライドと拡張の詳細については、http://www.bennadel.com/blog/2009-Using-Self-Executing-Function-Arguments-To-Override-Core-jQuery-Methods.htmを確認してください。クロージャー機能を追加しました。また、JQueryのサイトでプラグインのチュートリアルを確認してください。


7

MutationObserverAPIによって提供される「生の」ツールに加えて、DOM変異を処理するための「便利な」ライブラリが存在します。

考慮:MutationObserverは、DOMの各変更をサブツリーで表します。たとえば、特定の要素が挿入されるのを待っている場合、それはの子の奥深くにある可能性がありmutations.mutation[i].addedNodes[j]ます。

もう1つの問題は、ミューテーションに反応して独自のコードがDOMを変更する場合です-DOMを除外したいことがよくあります。

このような問題を解決する便利なライブラリーmutation-summary(免責事項:私は著者ではなく、満足しているユーザー)です。これにより、興味のあるもののクエリを指定して、それを正確に取得できます。

ドキュメントからの基本的な使用例:

var observer = new MutationSummary({
  callback: updateWidgets,
  queries: [{
    element: '[data-widget]'
  }]
});

function updateWidgets(summaries) {
  var widgetSummary = summaries[0];
  widgetSummary.added.forEach(buildNewWidget);
  widgetSummary.removed.forEach(cleanupExistingWidget);
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.