m2O

2007/03/14 (水)

Opera のユーザーJavaScript は「.js」か「.user.js」かで実行されるタイミングが違う

|  Opera のユーザーJavaScript は「.js」か「.user.js」かで実行されるタイミングが違う - m2O を含むブックマーク

知らなかった…

ユーザー JavaScript はあたかも皆様が訪問したページの一部であるかのように読み込まれ実行されます。ページの最初のスクリプトの直前に実行されます。ページにそれ自体のスクリプトが含まれていない場合、ユーザー JavaScript はページが読み込みを終了しようとする直前実行されます。また、ページの DOM の作成に先立ち実行されます。(ただし Greasemonkey スクリプトには適用しませんのでご注意ください。詳細は後述の Greasemonkey スクリプトの例 をお読みください。)

ユーザー JavaScript による制御 - ユーザー JavaScript の活用

Opera で多くの Greasemonkey スクリプトを実行できます。これらは Mozilla ブラウザシリーズ用に Greasemonkey の機能拡張とともに動作するよう設計された JavaScript になります。スクリプトファイルGreasemonkey 記法を利用していることを Opera に知らせるにはスクリプトを含むファイル名が .user.jsで終わっている必要があります(他の全ての .js ファイルは通常のユーザー JavaScript とみなされます)。 Greasemonkey 記法を利用するスクリプトはやや異なる方法で処理されます(既存のスクリプトとの互換性を保つため):

・window.opera.addEventListener および関連のメソッドや magic 関数変数の使用は許可されません。

ページの読み込み終了時、ページ用 DOM の作成後、かつ定義されたオンロードのハンドラの実行前に実行されます。

ユーザー JavaScript による制御 - 使用例 - Greasemonkey スクリプト

Opera 用のユーザーJavaScriptGreasemonkey で動かすために「.user.js」にしたら Opera で動かなくなってびっくりしました。スクリプトの中では

    document.addEventListener('DOMContentLoaded',func,false);

とやっていて、「.user.js」だと DOMContentLoaded 後にスクリプトが実行されるのが原因でした*1

これによって OperaGreasemonkey とで同じタイミングで実行されるのかと言うとそうでもないようで、Opera は前出のように onload の直前で、Greasemonkey は DOMContentLoaded の直後のような気がします(グリモンの方が早い(後述))。「Greasemonkey と同じスクリプトを使う」という目的以外では Opera で「.user.js」にする理由は無いでしょうね。

'DOMContentLoaded' は昨日はじめて知ってびっくりしたんですが、 'load' イベントだと画像なんかが読み終わるまで待たされるのに対し、 'DOMContentLoaded' イベントだとレンダリングとは無関係DOM構造を読み終えた時点で実行されるようです。これまで書いた user.js は全部これに置き換えたほうがいいかもしれませんね。

OperaユーザーJavaScript の実行タイミングをまとめると、

実行タイミング
ページ内にscript要素がある場合ページの最初のスクリプトの直前
ページ内にscript要素がない場合ページが読み込み終わってすぐ(通常はDOM構築前。でも.jsファイル開いたときとかはpreが出来てたなあ。)
.user.jsの場合onloadイベントの直前

となります。

*1Greasemonkeyでも動きません