如何在Greasemonkey 4中在DOM准备就绪时运行代码?

5

随着Firefox 57和Greasemonkey 4的更新,我的一些用户脚本出现了问题。在一些脚本中,我使用了:

document.addEventListener('DOMContentLoaded', doStuff, false);

在Greasemonkey中这已经不再起作用了。现在添加DOMContentLoaded事件的正确方法是什么?

附言:我检查过在注册事件时,DOM仍未准备就绪。

2个回答

4
我在 GreaseMonkey 升级到 4 版本后遇到了类似的问题,但是我使用了
addEventListener("DOMContentLoaded", function(){
  // …
});

当我试图修复我的用户脚本时,我最初注释掉了那个包装器,并放置了一个 instead

// @run-at document-end

元数据块中。这样,我确保了DOM已准备好,并且最初位于DOMContentLoaded包装器内的代码正确执行。

这个方法有效,但对于我的两个用户脚本,我实际上需要在任何页面脚本运行之前运行JavaScript并在DOM准备就绪时执行其他代码。结果发现,现在你必须把

// @run-at document-start

在元数据块中添加DOMContentLoaded包装器才能使您的window(或document)正常工作。

在以前的GreaseMonkey版本中,我可以省略这个并且它仍然可以正常运行。

然而,根据GreaseSpot Wikidocument-start不能保证在GreaseMonkey 4.0中正常工作,可能是由于异步执行或缺少WebExtensions重写附加组件的功能。

此外,使用document-start时,document.readyState将为"loading",但使用document-end或没有// @run-at时,将为"interactive"


有趣!对我来说,诀窍就是完全删除addEventListener函数。我将匿名函数内部的内容复制并粘贴到外部。我也没有设置@run-at。在之前的Greasemonkey版本中,我必须使用addEventListener函数,但现在可以省略所有内容。 - Yani2000
@Yani2000 那对我也起作用了,但只适用于一些脚本,其中我不需要区分在 DOM 加载之前和之后运行代码的情况。 - Sebastian Simon
有人刚刚点赞了这个答案。它还是最新的吗?我可能需要再次测试一下。 - Sebastian Simon

3

我仍然不知道在Greasemonkey 4中运行DOM ready代码的推荐方法是什么,但是在更改以下内容后:

document.addEventListener('DOMContentLoaded', doStuff, false);

to:

window.addEventListener('load', doStuff, false);

我的脚本又可以工作了。我刚开始尝试了基于这个答案的其他方法,因为我注意到我的基于jQuery的用户脚本仍然在工作(至少DOM ready部分是有效的)。

这个答案有点显而易见,但当我写问题时,我不确定自己是否跟上了Greasemonkey的变化(阅读所有异步内容),我期望DOMContentLoaded能够正常工作。


你尝试过使用 @run-at document-end 吗? - peterh
@peterh 我试过了,不幸的是,它已经不能工作了 :( - gal007
@gal007 我换了另一个火狐用户脚本扩展,我忘记它的名字了,但它运行得更好。 - peterh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接