web-dev-qa-db-ja.com

ページのコンテンツが表示される前にgreasemonkeyスクリプトを実行する方法は?

Firefox用のプラグインを作成し、それを行うためにグリースモンキースクリプトを使用しています(このツールを使用してユーザースクリプトをコンパイルします http://arantius.com/misc/greasemonkey/script-compiler )。

問題は、ページが完全にロードされた後にスクリプトが実行されることです。つまり、ユーザーは表示されたページを元の形式で表示し、スクリプトは私が行った変更を適用します。私の質問は、ページのコンテンツがユーザーに表示される前にユーザースクリプトを実行する方法があるので、ユーザーはWebサイトの最終バージョンのみを実行しますか?

26
khr2003

編集:この投稿は、Greasemonkeyに@run-atキーを実装する前に作成されました。Blaiseが指摘しているように、Greasemonkey 0.9.8から、ページの読み込みが開始されるとすぐにスクリプトが実行されるようになりました。

@run-at document-startはwikiで次のように説明されています。

スタートはバージョン0.9.8の時点で新しいです。スクリプトは、ドキュメントの読み込みが開始される前、つまりスクリプトが実行される前、または画像が読み込まれる前に実行されます。

これは、DOMの作成前にスクリプトを(潜在的に)実行することを意味し、一貫性のない/異常な動作につながる可能性があることに注意してください。この1行のドロップイン以上のものが(少し)必要になります。

Greasemonkey Wikiには、さらにいくつかの詳細があります: http://wiki.greasespot.net/Metadata_Block#.40run-at

補足:私が渡さなければならない情報は、特にブラウザのGreasemonkeyに関連しています。 @run-at document-startがスクリプトコンパイラでうまく機能するかどうかはわかりません-危険な生活を送ることをお勧めします。テストして調べてください! ;]



現在、ページが読み込まれる前にユーザースクリプトを実行することはできません。

現在のバージョンのGreasemonkeyを使用してちらつきを止めるには、 Greasemonkey wiki)で説明されているように、Firefoxプロファイルにユーザースタイルを追加してみてください(スクリプトを使用して元に戻します)。 ただし、これを利用するには、各ユーザーが同じことを行う必要があります。

これは長い間望まれていたものであり、GreasemonkeyのGithubサイトで issue#11 を調べたところ、動作するプロトタイプが作成されたようです(ただし、これをリリースバージョンafaikに追加するためのタイムスケールはありません)

27
kwah

@kwahの回答で提案されているように、@run-at document-startを使用すると、操作したいコンテンツがドキュメントの本文に含まれる前にスクリプトが実行されました。回避策として、スクリプトをdocument.readyState == "complete"まで(または20秒が経過するまで)5回/秒で実行する間隔を設定しました。

これは私の場合はうまくいきました:

// ==UserScript==
// ...
// @run-at      document-start
// ==/UserScript==

var greasemonkeyInterval = setInterval(greasemonkey, 200);
var greasemonkeyStart = (new Date()).getTime();

function greasemonkey() {

    // ...

    // waiting for readyState (or timeout)
    if (
        (new Date()).getTime() - greasemonkeyStart > 20000
        || document.readyState == "complete"
    ) {
        clearInterval(greasemonkeyInterval);
    }

};

コンテンツがdocumentreadyにあることを確信している場合は、次のようなものがより望ましいと思います。

function greasemonkey() {

    if (
        document.readyState != "interactive"
        && document.readyState != "complete"
    ) {
        return;
    }

    // ...

    clearInterval(greasemonkeyInterval);

}
3

以前の回答に加えて、FirefoxとGreaseMonkeyの以前のバージョンと同じように、完璧に機能するソリューションを見つけました。まず、run-atを最も早い瞬間に設定する必要があるため、document-start:

// @run-at      document-start

DOMはおそらくまだロードされていないため、ドキュメントがインタラクティブのreadyStateを取得するのを待ちます。

document.onreadystatechange = function () {
    if (document.readyState === "interactive") {
       // Do something
    }
}

Greasemonkeyはドキュメントエンドとほぼ同じように実装されていますが、上記の手法の方が高速であることに気づきました。これを使用すると、DOMの変更が開始されたときにページの画面が点滅/ジャンプし、ユーザースクリプトで意図したとおりにページが直接読み込まれるという、Firefoxで発生したすべての問題が解決されました。

2
Ossie7