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


1 Answers

数年後、正式により良い解決法が完成しました。 DOM4変異オブザーバは、非難されたDOM3変異イベントの代わりとなります。 現在のところMutationObserver (または古いバージョンのChromeでは、ベンダープレフィックスのWebKitMutationObserverとして最新のブラウザに実装されています

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

この例では、 documentとそのサブツリー全体のDOM変更をリッスンし、要素の変更や構造の変更を発生させます。 ドラフト仕様には、有効な突然変異リスナーのプロパティの完全なリストがあります

子リスト

  • ターゲットの子への突然変異を観察する場合はtrue設定しtrue

属性

  • ターゲットの属性への突然変異を観察する場合はtrue設定しtrue

characterData

  • ターゲットのデータへの突然変異を観察する場合はtrue設定しtrue

サブツリー

  • 突然変異がターゲットだけでなくターゲットの子孫にも見られるようにするには、 true設定しtrue

attributeOldValue

  • attributesがtrueに設定され、ターゲットの属性値が突然変異を記録する必要がある場合は、trueに設定します。

characterDataOldValue

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

attributeFilter

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

(このリストは2014年4月現在のものであり、仕様の変更を確認することができます)

Question

基本的には、DIVの内容が変更されたときにスクリプトを実行させたいと思っています。 スクリプトは別々のもの(クロム拡張とウェブページスクリプトのコンテンツスクリプト)なので、DOM状態の変化を観察するだけの方法が必要です。 私はポーリングを設定することができましたが、それはちょっとしたことです。




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

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

  • 文字通りDOMの変更を検出するMutationObserverdocs

    • HTMLコンテンツがページにロードされるときに変更する方法
    • MutationObserverがDOM全体のノードを検出するパフォーマンス 。
  • DOMイベントを送信してコンテンツの変更を通知するサイトのイベントリスナー

    • pjax:end多くのpjaxベースのサイト、例えばGitHub、
      「 pjaxのロードの前後にjQueryを実行する方法」を参照してください。
    • ChromeブラウザでのGoogle検索などで使用されるwindow上のmessage
      Chrome拡張機能でGoogle検索の更新を検出する
    • Youtubeで使用されるdocument spfdone
      「 Youtubeでページナビゲーションを検出する方法と、ページがレンダリングされる前にHTMLを変更する方法」を参照してください。
  • setIntervalによるDOMの定期的なチェック
    明らかに、これはID /セレクタによって特定された特定の要素が現れるのを待つ場合にのみ機能し、何らかの種類の既存コンテンツのフィンガープリントを作成しない限り、新しい動的追加コンテンツを普遍的に検出することはできません。

  • 注入されたDOMスクリプト内で履歴APIをクローキングする:

    document.head.appendChild(document.createElement('script')).text = '(' +
        function() {
            // injected DOM script is not a content script anymore, 
            // it can modify objects and functions of the page
            var _pushState = history.pushState;
            history.pushState = function(state, title, url) {
                _pushState.call(this, state, title, url);
                window.dispatchEvent(new CustomEvent('state-changed', {detail: state}));
            };
            // repeat the above for replaceState too
        } + ')(); this.remove();'; // remove the DOM script element
    
    // And here content script listens to our DOM script custom events
    window.addEventListener('state-changed', function(e) {
        console.log('History state changed', e.detail, location.hash);
        doSomething();
    });
    
  • hashchangepopstateイベントを聞く:

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


拡張機能固有: background / イベントページの URL変更を検出します。

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

  • マニフェスト.json:
    背景/イベントページを宣言する
    コンテンツスクリプトを宣言する
    "tabs" permission追加しpermission

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





Related