基本的に私はDIV
の内容が変わったときにスクリプトを実行させたいのです。スクリプトは独立しているため(Chrome拡張機能のコンテンツスクリプトとWebページスクリプト)、DOMの状態の変化を簡単に観察する方法が必要です。私は投票を設定することができましたが、それはずさんなようです。
数年後、今では公式により良い解決策があります。 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の変更を監視し、構造的な変更と同様に要素の属性に対する変更でも起動します。ドラフト仕様には、有効な 変換リスナープロパティ の完全なリストがあります。
childList
- ターゲットの子供への突然変異が観察される場合は
true
に設定します。属性
- ターゲットの属性への突然変異を観察する場合は
true
に設定します。characterData
- ターゲットのデータへの突然変異を観察する場合は
true
に設定します。サブツリー
- 突然変異をターゲットにするだけでなく、ターゲットの子孫も観察する場合は
true
に設定します。attributeOldValue
true
がtrueに設定され、突然変異が記録される必要がある前にターゲットの属性値が設定されている場合はattributes
に設定します。characterDataOldValue
true
がtrueに設定されていて、突然変異が記録される必要がある前にターゲットのデータをcharacterData
に設定します。attributeFilter
- すべての属性の変更を監視する必要があるとは限らない場合は、(名前空間なしで)属性のローカル名のリストに設定します。
(このリストは2014年4月現在のものです。変更については仕様を確認してください。)
多くのサイトはAJAXを使ってコンテンツを動的に追加/表示/変更します。サイト内ナビゲーションの代わりに使用されることがあるので、現在のURLはプログラム的に変更され、この場合ページはリモートサーバーから完全に取得されないため、コンテンツスクリプトはブラウザによって自動的に実行されません。
MutationObserver( docs )は文字通りDOMの変更を検出します。
DOMイベントを送信してコンテンツの変更を通知するサイトのイベントリスナ
document
のpjax:end
GitHub、message
上のwindow
ChromeブラウザでGoogle検索spfdone
上のdocument
、setIntervalによるDOMの定期チェック
これは、id/selectorで識別される特定の要素が表示されるのを待つ場合にのみ有効であり、既存のものに何らかのフィンガープリントを作成しない限り、動的に追加される新しいコンテンツを普遍的に検出できません。内容.
挿入された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();
});
hashchange 、 popstate 件のイベントを聞いています:
window.addEventListener('hashchange', function(e) {
console.log('URL hash changed', e);
doSomething();
});
window.addEventListener('popstate', function(e) {
console.log('State changed', e);
doSomething();
});
ナビゲーションを扱うための高度なAPIがあります: webNavigation 、 webRequest 、しかし我々は単純な chrome.tabs.onUpdatedコンテンツスクリプトへのメッセージ :
manifest.json:
背景/イベントページ を宣言
コンテンツスクリプト を宣言する"tabs"
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();
}
});
あなたがdivを変更している方法に応じて別のアプローチ。 JQueryを使用してdivの内容をそのhtml()メソッドで変更する場合は、そのメソッドを拡張して、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()メソッドの結果を返すことを忘れないでください。
メソッドのオーバーライドと拡張の詳細については、 を参照してください。 jQuery-Methods.htm 、ここでクロージャ関数を省略しました。 JQueryのサイトにあるプラグインのチュートリアルも調べてください。
MutationObserver
API によって提供される「生の」ツールに加えて、DOM変異を扱うための「便利な」ライブラリがあります。
考慮してください。MutationObserverは、各DOMの変更をサブツリーで表します。たとえば、ある要素が挿入されるのを待っているのであれば、それはmutations.mutation[i].addedNodes[j]
の子の奥深くにあるかもしれません。
もう一つの問題は、突然変異に反応してあなた自身のコードが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);
}