【问题标题】:Understanding how Greasemonkey runs user scripts了解 Greasemonkey 如何运行用户脚本
【发布时间】:2026-01-13 17:20:06
【问题描述】:

我正在学习 Greasemonkey,希望对网页进行一些改进。

我认为我对 JavaScript 有很好的掌握,但我不明白 Greasemonkey 用户脚本在文档呈现的哪个时间点被执行。

例如,如果文档内部有原生的 JavaScript 将一些元素插入页面怎么办。我希望我的 Greasemonkey 脚本仅在 JS 完成后运行。

假设这是我正在尝试使用 Greasemonkey 修改的文档

<html>
 <script>
   //insert a button with id="mybutton"
 </script>
</html>

我希望&lt;script&gt; 代码在我的 Greasemonkey 脚本运行之前完成,因为我想改变它的背景颜色。

【问题讨论】:

  • Greasemonkey 在equivalentDOMContentLoaded 处插入代码。如果要在加载外部 js 文件等外部内容后执行代码,请使用unsafeWindow.onload = function(){ ... }

标签: javascript greasemonkey


【解决方案1】:

Greasemonkey runs at the DOMContentLoaded event 默认情况下。这意味着除了可能大图像和一些 javascript 添加的内容(在load 事件或 AJAX 输入内容上触发的脚本)之外,所有内容都将在页面中。

如果您想等到大型媒体已加载并且“onload”脚本已运行,请使用:

window.addEventListener ("load", Greasemonkey_main, false);

function Greasemonkey_main () {

    //***** PUT YOUR GREASEMONKEY CODE HERE.
}

不要像其他人建议的那样使用 unsafeWindow.onload = function(){ ... }window.onload = function() { /* logic here */ }These are not only poor practice/won't work in GM,但在这种情况下,unsafeWindow 是不必要的安全风险。



但是,处理 JS 添加的内容:

由于您表示您关心的节点是通过javascript添加的,因此等待load事件通常是行不通的。 JS可以随时添加、删除或编辑节点。

在这种情况下,最好的方法是轮询您感兴趣的元素 ("#mybutton")。见this answer to "Fire Greasemonkey script on AJAX request"

【讨论】:

  • 从 Greasemonkey 3.6 开始,您还可以使用 // @run-at document-idle,参见 *.com/a/41667350/6216216
  • @Leviathan,请谨慎使用,因为它是从 Chrome 借来的,但与Chrome does 的操作方式和Tampermonkey does 的操作方式不同。如果您使用该指令,脚本在不同浏览器中的行为可能会有所不同。