jQuery 不会在 Firefox WebExtensions 中添加事件侦听器

jQuery won't add event listeners in Firefox WebExtensions

我目前正在 Firefox 下编写 WebExtension,我一直坚持与页面交互。我有一个需要访问页面变量的内容脚本,例如 jQuery instance.

我正在使用

访问 jQuery
var $ = window.wrappedJSObject.$;

这很好用,我可以向页面等添加 DOM 元素,但事件处理存在问题。例如,这段代码工作正常:

$('#nav-bar').append('<img src="..."/>'); // Works great

但是当我尝试添加事件处理程序时,它失败了

$('#button').click(function () {}); // Fails

错误消息说

Permission denied to access property "handler"

我的猜测是 Firefox WebExtensions 有一些安全措施可以防止轻易添加事件处理程序,但我一直没有找到原因。我怎样才能让它发挥作用?

您的问题是您试图在内容脚本进程(匿名 click 侦听器)中定义一个函数,但它作为事件处理程序从页面上下文中执行。这导致该函数无法供 jQuery 操作,也无法实际添加为侦听器。

对此的正确解决方案是将在页面上下文中运行的代码与在内容脚本进程中执行的代码分开。您希望在页面上下文中运行的任何代码都应使用 Building a Chrome Extension - Inject code in a page using a Content script 中描述的方法之一进行处理。然后,您应该通过任何可用的常规方法在它们之间来回通信。

我建议您下载想要使用的 jQuery 版本,将其包含在您的扩展中,并将其包含在您作为内容脚本注入的脚本中。然后,您可以使用该版本的 jQuery 来完成您正在做的大部分事情。当您 真的 需要操纵页面上下文 jQuery 对象的状态时,您可以通过上面链接的答案中的各种方法专门访问它。如果您希望您的扩展仅是 Firefox,您可以使用 window.wrappedJSObject 来访问存在于页面上下文中的 jQuery,用于那些您确实需要访问的内容。这样做有其自身的局限性。其中一个你已经遇到了。

以 cross-browser 兼容的方式做您似乎想做的事情所花费的编码工作量与以 Firefox 特定方式处理您自己的情况所花费的编码工作量一样多(可以选择这样做).除了 cross-browser 兼容的好处之外,还使它更 future-proof。