「ページ読み込みやタブ切り替えを監視」の編集履歴(バックアップ)一覧はこちら

ページ読み込みやタブ切り替えを監視 - (2013/04/19 (金) 10:59:04) の1つ前との変更点

追加された行は緑色になります。

削除された行は赤色になります。

*DOMイベントを利用する -[[Using Firefox 1.5 caching | MDN>https://developer.mozilla.org/ja/docs/Using_Firefox_1.5_caching]] -[[Gecko 固有の DOM Event | MDN>https://developer.mozilla.org/ja/docs/Gecko-Specific_DOM_Events]] #highlight(javascript){{ // タブの切り替え gBrowser.mTabContainer.addEventListener("TabSelect", function(){}, false); // ページドキュメントの読み込み gBrowser.mPanelContainer.addEventListener("DOMContentLoaded", function(){}, false); // load, unload の Firefox独自版(キャッシュ処理が違う) gBrowser.mPanelContainer.addEventListener("pageshow", function(){}, false); gBrowser.mPanelContainer.addEventListener("pagehide", function(){}, false);}} **メモ DOMContentLoaded, pageshow, pagehide はフレームからも発行されるので、aEvent.target.defaultView でどこから発行されたのかを見極める必要がある。 *EventListener を利用する -[[Progress Listeners - Code snippets | MDN>https://developer.mozilla.org/en-US/docs/Code_snippets/Progress_Listeners]] -[[nsIWebProgress - XPCOM Interface Reference | MDN>https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIWebProgress]] -[[nsIWebProgressListener - XPCOM Interface Reference | MDN>https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIWebProgressListener]] #highlight(javascript){{ var Ci = Components.interfaces; var myListener = { _oldURI : null, init : function() { gBrowser.addProgressListener(this); this._oldURI = gBrowser.currentURI; }, uninit : function() { gBrowser.removeProgressListener(this); }, QueryInterface : function(aIID) { if (aIID.equals(Ci.nsIWebProgressListener) || aIID.equals(Ci.nsISupportsWeakReference) || aIID.equals(Ci.nsISupports)) return this; throw Components.results.NS_NOINTERFACE; }, onStateChange : function(aWebProgress, aRequest, aFlag, aStatus) { // myListener を二つ以上のタブ/ブラウザで使うなら、onStateChangeイベントを起こした // タブ/ウインドウを取得するのに aWebProgress.DOMWindow を使用 if(aFlag & Ci.nsIWebProgressListener.STATE_START) { // ロードイベントが始まったときに実行 } if(aFlag & Ci.nsIWebProgressListener.STATE_STOP) { // ロードが終わったときに実行 } if (aFlag & Ci.nsIWebProgressListener.STATE_STOP && aFlag & Ci.nsIWebProgressListener.STATE_IS_NETWORK) { // ネットワークの読み込みが終わったときに実行 } }, onLocationChange : function(aWebProgress, aRequest, aURI) { // ロケーションバーが変更されたとき実行。 // myListener を二つ以上のタブ/ブラウザで使うなら、onStateChangeイベントを起こした // タブ/ウインドウを取得するのに aWebProgress.DOMWindow を使用。 if (aURI.equalsExceptRef(this._oldURI)) { // アンカーでのロケーション変更の場合。 return; } this._oldURI = aURI; if (aWebProgress.isLoadingDocument) { if (aURI.spec == "about:blank") { // 空白ページに移動した場合。 // STATE_STOPが発行されない=onStateChangeが期待できないので注意(メモ3)。 } else { // 読み込み中の場合。 } } else { // 読み込み完了状態の場合。タブ切り替え時など。 } }, onProgressChange : function(aWebProgress, aRequest, curSelf, maxSelf, curTot, maxTot) { }, onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage) { }, onSecurityChange : function(aWebProgress, aRequest, aState) { } } }} #highlight(javascript){ myListener.init();} **メモ1 xul:browserにリスナー登録する場合は第2引数に受け取るイベントを指定するNotifyMaskを設定できるが、xul:tabbrowser(gBrowser)に登録する場合は指定できない?指定しても機能しない? →gBrowserに登録するリスナーが全部で一つだけの場合は機能するっぽい? 拡張機能を色々入れてリスナーをいくつも登録したりする状況だと駄目みたい? →Minefield4.2a1pre で第2引数が廃止され、第2引数を指定していると警告ダイアログが表示されるようになった。 -[[Bug 608628 – aMask argument to tabbrowser's addProgressListener is only used when not in tabbed mode>https://bugzilla.mozilla.org/show_bug.cgi?id=608628]] **メモ2 onStateChange で aFlag を利用した状況判定について。STATE_STOP と STATE_IS_REQUEST の二つは、単独およびこの二つのみの組み合わせで使用するのは避けるべき? 監視対象にエラーコンソールのような刻一刻と表示を変化させるコンテンツをロードさせたりすると大変な事になる。 以下のコードで onStateChange イベントがどのように発行されているか観察できるので見てみると良い。 #highlight(javascript){{ onStateChange : function(aWebProgress, aRequest, aFlag, aStatus) { var message = ''; ['STATE_START', 'STATE_STOP', 'STATE_REDIRECTING', 'STATE_TRANSFERRING', 'STATE_IS_REQUEST', 'STATE_IS_DOCUMENT', 'STATE_IS_NETWORK', 'STATE_IS_WINDOW', 'STATE_RESTORING'] .forEach(function(flag){ if(aFlag & Ci.nsIWebProgressListener[flag]) { message += '\n' + flag; } }); if (aWebProgress.isLoadingDocument) { message += '\n読み込み中'; } if (aRequest) { message += '\naRequest有り'; } Application.console.log(message); },}} **メモ3 最後のタブを閉じて about:blank のタブだけ残った状態にする時や、あるいは新しいタブを開いた時にも onLocationChange が呼ばれる。この際 aWebProgress.isLoadingDocument は true になっているが、その後 STATE_STOP などは発行されない。
*DOMイベントを利用する -[[Using Firefox 1.5 caching | MDN>https://developer.mozilla.org/ja/docs/Using_Firefox_1.5_caching]] -[[Gecko 固有の DOM Event | MDN>https://developer.mozilla.org/ja/docs/Gecko-Specific_DOM_Events]] #highlight(javascript){{ // タブの切り替え gBrowser.mTabContainer.addEventListener("TabSelect", function(){}, false); // ページドキュメントの読み込み gBrowser.mPanelContainer.addEventListener("DOMContentLoaded", function(){}, false); // load, unload の Firefox独自版(キャッシュ処理が違う) gBrowser.mPanelContainer.addEventListener("pageshow", function(){}, false); gBrowser.mPanelContainer.addEventListener("pagehide", function(){}, false);}} **メモ DOMContentLoaded, pageshow, pagehide はフレームからも発行されるので、aEvent.target.defaultView でどこから発行されたのかを見極める必要がある。 *EventListener を利用する -[[Progress Listeners - Code snippets | MDN>https://developer.mozilla.org/en-US/docs/Code_snippets/Progress_Listeners]] -[[nsIWebProgress - XPCOM Interface Reference | MDN>https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIWebProgress]] -[[nsIWebProgressListener - XPCOM Interface Reference | MDN>https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIWebProgressListener]] #highlight(javascript){{ var Ci = Components.interfaces; var myListener = { init : function() { gBrowser.addProgressListener(this); }, uninit : function() { gBrowser.removeProgressListener(this); }, QueryInterface : function(aIID) { if (aIID.equals(Ci.nsIWebProgressListener) || aIID.equals(Ci.nsISupportsWeakReference) || aIID.equals(Ci.nsISupports)) return this; throw Components.results.NS_NOINTERFACE; }, onStateChange : function(aWebProgress, aRequest, aFlag, aStatus) { // myListener を二つ以上のタブ/ブラウザで使うなら、onStateChangeイベントを起こした // タブ/ウインドウを取得するのに aWebProgress.DOMWindow を使用 if(aFlag & Ci.nsIWebProgressListener.STATE_START) { // ロードイベントが始まったときに実行 log(aRequest.name); // aRequest.name は多くの場合リクエストURIを示す } if(aFlag & Ci.nsIWebProgressListener.STATE_STOP) { // ロードが終わったときに実行 } if (aFlag & Ci.nsIWebProgressListener.STATE_STOP && aFlag & Ci.nsIWebProgressListener.STATE_IS_NETWORK) { // ネットワークの読み込みが終わったときに実行 } }, onLocationChange : function(aWebProgress, aRequest, aURI) { // ロケーションバーが変更されたとき実行。 // myListener を二つ以上のタブ/ブラウザで使うなら、onStateChangeイベントを起こした // タブ/ウインドウを取得するのに aWebProgress.DOMWindow を使用。 if (aFlags & Ci.nsIWebProgressListener.LOCATION_CHANGE_SAME_DOCUMENT) { // アンカーでのロケーション変更の場合。 return; } if (aWebProgress.isLoadingDocument) { if (aURI.spec == "about:blank") { // 空白ページに移動した場合。 // STATE_STOPが発行されない=onStateChangeが期待できないので注意(メモ3)。 } else { // 読み込み中の場合。 } } else { // 読み込み完了状態の場合。タブ切り替え時など。 } }, onProgressChange : function(aWebProgress, aRequest, curSelf, maxSelf, curTot, maxTot) { }, onStatusChange : function(aWebProgress, aRequest, aStatus, aMessage) { }, onSecurityChange : function(aWebProgress, aRequest, aState) { } } }} #highlight(javascript){ myListener.init();} **メモ1 xul:browserにリスナー登録する場合は第2引数に受け取るイベントを指定するNotifyMaskを設定できるが、xul:tabbrowser(gBrowser)に登録する場合は指定できない?指定しても機能しない? →gBrowserに登録するリスナーが全部で一つだけの場合は機能するっぽい? 拡張機能を色々入れてリスナーをいくつも登録したりする状況だと駄目みたい? →Minefield4.2a1pre で第2引数が廃止され、第2引数を指定していると警告ダイアログが表示されるようになった。 -[[Bug 608628 – aMask argument to tabbrowser's addProgressListener is only used when not in tabbed mode>https://bugzilla.mozilla.org/show_bug.cgi?id=608628]] **メモ2 onStateChange で aFlag を利用した状況判定について。STATE_STOP と STATE_IS_REQUEST の二つは、単独およびこの二つのみの組み合わせで使用するのは避けるべき? 監視対象にエラーコンソールのような刻一刻と表示を変化させるコンテンツをロードさせたりすると大変な事になる。 以下のコードで onStateChange イベントがどのように発行されているか観察できるので見てみると良い。 #highlight(javascript){{ onStateChange : function(aWebProgress, aRequest, aFlag, aStatus) { var message = ''; ['STATE_START', 'STATE_STOP', 'STATE_REDIRECTING', 'STATE_TRANSFERRING', 'STATE_IS_REQUEST', 'STATE_IS_DOCUMENT', 'STATE_IS_NETWORK', 'STATE_IS_WINDOW', 'STATE_RESTORING'] .forEach(function(flag){ if(aFlag & Ci.nsIWebProgressListener[flag]) { message += '\n' + flag; } }); if (aWebProgress.isLoadingDocument) { message += '\n読み込み中'; } if (aRequest) { message += '\naRequest有り'; } Application.console.log(message); },}} **メモ3 最後のタブを閉じて about:blank のタブだけ残った状態にする時や、あるいは新しいタブを開いた時にも onLocationChange が呼ばれる。この際 aWebProgress.isLoadingDocument は true になっているが、その後 STATE_STOP などは発行されない。

表示オプション

横に並べて表示:
変化行の前後のみ表示: