如何在显示页面内容之前运行greasemonkey脚本?

时间:2011-02-12 15:04:37

标签: javascript firefox firefox-addon greasemonkey

我正在为Firefox编写插件并使用greasemonkey脚本来执行此操作(我使用此工具编译用户脚本http://arantius.com/misc/greasemonkey/script-compiler)。

问题是脚本在页面完全加载后运行。这意味着用户将以原始形式查看已查看的页面,然后脚本将应用我所做的更改。我的问题是有一种方法在页面内容显示给用户之前运行用户脚本,因此用户只会访问网站的最终版本吗?

3 个答案:

答案 0 :(得分:26)

编辑:这篇文章是在Greasemonkey中实现@run-at键之前创建的 - 正如Blaise所说,来自Greasemonkey 0.9.8,您现在可以在页面开始加载后立即执行脚本。

@run-at document-start在wiki中描述如下:

  

从版本0.9.8开始是新的。该脚本将在任何之前运行   文档开始加载,因此在任何脚本运行或图像加载之前。

请注意,这意味着在创建DOM之前(可能)运行脚本,并可能导致某些不一致/异常行为。你需要(一点点)不仅仅是这个单行插入。

在Greasemonkey Wiki上还有一些细节: http://wiki.greasespot.net/Metadata_Block#.40run-at

旁注:我必须提供的信息与浏览器中的Greasemonkey特别相关。我不确定@run-at document-start是否适用于脚本编译器 - 我建议生活危险..测试并找出答案! ]



目前无法在页面加载之前运行用户脚本。

要使用当前版本的Greasemonkey停止闪烁,您可以尝试在Firefox配置文件中添加用户样式(然后使用脚本撤消),如Greasemonkey wiki所述,但这也会要求每个用户都这样做,以便从中受益。

很长一段时间都需要这样的东西,并在Greasemonkey的Github网站上查看issue #1103,似乎已经制作了一个工作原型(但是没有时间尺度可以添加到发布版本afaik)。

答案 1 :(得分:2)

使用@kwah答案中建议的@run-at document-start我在我想要操作的内容之前执行的脚本是在文档正文中。作为解决方法,我设置了一个间隔运行我的脚本5次/秒,直到document.readyState == "complete"(或直到20秒)。

这适用于我的案例:

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

};

如果你更确定内容会在文档准备就绪,我认为这样的内容会更优选:

function greasemonkey() {

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

    // ...

    clearInterval(greasemonkeyInterval);

}

答案 2 :(得分:2)

除了之前的答案,我还发现了一个完美无瑕的解决方案,就像之前版本的Firefox&的GreaseMonkey。 首先,必须将run-at设置为最早的时刻,因此文档启动:

// @run-at      document-start

因为DOM可能尚未加载,所以请等待文档获得一个readyState of interactive:

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

虽然Greasemonkey与document-end的实现方式大致相同,但我注意到上述技术的工作速度更快。 使用它解决了我在Firefox中遇到的所有问题,当DOM更改启动时,页面上有闪烁/跳转屏幕,并按照用户脚本的意图直接加载页面。