我正在为Firefox编写插件并使用greasemonkey脚本来执行此操作(我使用此工具编译用户脚本http://arantius.com/misc/greasemonkey/script-compiler)。
问题是脚本在页面完全加载后运行。这意味着用户将以原始形式查看已查看的页面,然后脚本将应用我所做的更改。我的问题是有一种方法在页面内容显示给用户之前运行用户脚本,因此用户只会访问网站的最终版本吗?
答案 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更改启动时,页面上有闪烁/跳转屏幕,并按照用户脚本的意图直接加载页面。