440

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

4

5 に答える 5

532

長い間、DOM3ミューテーションイベントは利用可能な最善のソリューションでしたが、パフォーマンス上の理由から非推奨になりました。DOM4 Mutation Observersは、廃止されたDOM3ミューテーションイベントの代わりになります。それらは現在、次のように(または古いバージョンのChromeではベンダープレフィックスとして)最新のブラウザに実装されています。MutationObserverWebKitMutationObserver

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
  //...
});

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

childList

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

属性

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

characterData

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

サブツリー

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

attributeOldValue

  • ミューテーションを記録する必要がある前に、trueifに設定してtrueに設定し、ターゲットの属性値を設定します。attributes

characterDataOldValue

  • ミューテーションを記録する必要がある前に、trueifに設定してtrueに設定し、ターゲットのデータを設定します。characterData

attributeFilter

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

(このリストは2014年4月現在のものです。仕様に変更がないか確認してください。)

于 2012-07-18T16:39:10.890 に答える
223

編集

この回答は廃止されました。apsillersによる回答を参照してください。

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

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

ここで実際の例を参照してください。

于 2010-05-16T17:25:59.500 に答える
69

多くのサイトでは、コンテンツを動的に追加、表示、変更するために AJAX/XHR/fetch を使用し、サイト内ナビゲーションの代わりに window.history API を使用しているため、現在の URL はプログラムによって変更されます。このようなサイトは、Single Page Application の略で SPA と呼ばれます。


ページ変更を検出する通常の JS メソッド

  • MutationObserver ( docs ) を使用して、文字通り DOM の変更を検出します。

    情報/例:

  • DOM イベントを送信してコンテンツの変更を通知するサイトのイベント リスナー:

  • setInterval による DOM の定期的なチェック:
    明らかにこれは、ID/セレクターによって識別される特定の要素が表示されるのを待っている場合にのみ機能し、何らかのフィンガープリンティングを発明しない限り、新しく動的に追加されたコンテンツを普遍的に検出することはできません。既存のコンテンツ。

  • クローキング履歴 API :

    let _pushState = History.prototype.pushState;
    History.prototype.pushState = function (state, title, url) {
      _pushState.call(this, state, title, url);
      console.log('URL changed', url)
    };
    
  • hashchangepopstateイベントのリッスン:

    window.addEventListener('hashchange', e => {
      console.log('URL hash changed', e);
      doSomething();
    });
    window.addEventListener('popstate', e => {
      console.log('State changed', e);
      doSomething();
    });
    

PS これらのメソッドはすべて、WebExtension のcontent scriptで使用できます。これは、我々が見ているケースが history.pushState または replaceState によって URL が変更された場合であり、ページ自体は同じコンテンツ スクリプト環境で同じままであったためです。

于 2016-09-15T10:36:21.970 に答える
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() 関数への呼び出しを渡します。元の html() メソッドの結果を返すことを忘れないでください。これは、JQuery がメソッド チェーンのためにそれを想定しているためです。

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

于 2012-05-24T17:01:18.793 に答える
7

MutationObserverAPIによって提供される「生の」ツールに加えて、DOM ミューテーションを操作するための「便利な」ライブラリが存在します。

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

もう 1 つの問題は、ミューテーションに反応して独自のコードが 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);
}
于 2016-05-10T12:00:26.953 に答える