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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4978736/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 15:03:27  来源:igfitidea点击:

how to run greasemonkey script before the page content is displayed?

javascriptfirefoxfirefox-addongreasemonkey

提问by khr2003

I am writing a plug-in for Firefox and using greasemonkey script to do that (I compile the user script using this tool http://arantius.com/misc/greasemonkey/script-compiler).

我正在为 Firefox 编写一个插件并使用greasemonkey 脚本来做到这一点(我使用这个工具http://arantius.com/misc/greasemonkey/script-compiler编译用户脚本)。

The issue is that the script is run after the page is fully loaded. Meaning the user would see the viewed page in its original form and then the script will apply the changes that I made. My question is there a way to run the user script before the contents of the page is displayed to the user, so the user would only the final version of the website?

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

回答by kwah

EDIT: This post was created prior to the implementation of the @run-atkey in Greasemonkey - as noted by Blaise, from Greasemonkey 0.9.8 you may now have the script executed as soon as the page begins to load.

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

@run-at document-startis described in the wiki as follows:

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

Start is new as of version 0.9.8. The script will run before any document begins loading, thus before any scripts run or images load.

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

Note that this means having the script run (potentially) prior to the creation of the DOM and may lead to some inconsistent/unusual behaviour. You will need (a little) more than just this one-line drop-in.

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

There are a few more details over at the Greasemonkey Wiki: http://wiki.greasespot.net/Metadata_Block#.40run-at

Greasemonkey Wiki 上有更多详细信息:http: //wiki.greasespot.net/Metadata_Block#.40run-at

Side-note: The information I have to hand is specifically related to Greasemonkey in the browser. I am unsure whether @run-at document-startworks well with the script compiler - I suggest living dangerously.. Test it and find out! ;]

旁注:我必须提供的信息与浏览器中的 Greasemonkey 相关。我不确定@run-at document-start脚本编译器是否可以正常工作 - 我建议危险地生活.. 测试它并找出答案!;]





It is not currently possible to run a user script before the page loads.

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

To stop the flicker using current versions of Greasemonkey, you could try adding a user-style to your Firefox profile (which is then undone using the script) as described at the Greasemonkey wikibut this would also require each of your users to do the same to benefit from this.

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

It is something that has been desired for a long time and looking through issue #1103on Greasemonkey's Github site, a working prototype appears to have been made (but there is no timescale for this to be added to a release version afaik).

这是长期以来一直需要的东西,在 Greasemonkey 的 Github 站点上查看问题 #1103,似乎已经制作了一个工作原型(但没有时间表将其添加到发布版本 afaik)。

回答by Ossie7

In addition to the previous answers I've found a solution that works flawlessly, just like previous versions of Firefox & GreaseMonkey. First off, run-at must be set to the earliest moment, so document-start:

除了之前的答案之外,我还找到了一个完美无缺的解决方案,就像以前版本的 Firefox 和 GreaseMonkey 一样。首先,run-at 必须设置为最早的时刻,所以 document-start:

// @run-at      document-start

Because the DOM is probably not loaded yet, wait for the document to get a readyState of interactive:

因为 DOM 可能还没有加载,所以等待文档获得交互式的 readyState:

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

While Greasemonkey implements more or less the same with document-end, I've noticed that the technique above works faster. Using this has resolved all issues I had in Firefox with flashing / jumping screens on pages when the DOM changes kicked in and directly loads the page as intended with the userscript.

虽然 Greasemonkey 与文档端实现或多或少相同,但我注意到上述技术工作得更快。使用它解决了我在 Firefox 中遇到的所有问题,当 DOM 更改开始时,页面上出现闪烁/跳转屏幕,并按照用户脚本的预期直接加载页面。

回答by Jonas ?ppelgran

Using the @run-at document-startas suggested in the answer by @kwah my script executed before the content I wanted to manipulate was in the document body. As a work-around I set up an interval running my script 5 times/second until document.readyState == "complete"(or until 20 seconds have passed).

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

This worked well for my case:

这对我的情况很有效:

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

};

If you're more sure about that the content will be there at documentready I think something like this would be more preferable:

如果您更确定内容将在 documentready 中,我认为这样的事情会更可取:

function greasemonkey() {

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

    // ...

    clearInterval(greasemonkeyInterval);

}