jQuery $(document).off() not working in Chrome extension
我已经创建了一个基于 https://thoughtbot.com/blog/how-to-make-a-chrome-extension 的 Chrome 扩展程序(查看最后完成的文件)
我做了两处更改:我使用 jQuery 3.1.1 最小化而不是上面页面中给出的旧版本,并且我更改了 content.js:
1 2 3 4 5 6 7
| chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message ==="clicked_browser_action" ) {
$(document).off("touchmove mousewheel mousemove scroll");
}
}
); |
当我单击扩展程序按钮并打开相应的测试页面时,$(document).off() 命令不起作用。它不会给出错误,只是什么都不做。
我已经检查过了。如果我在要影响的页面上的控制台中键入 $(document).off("touchmove mousewheel mousemove scroll");,它可以正常工作。如果在扩展程序中运行,则不是。
我尝试检查扩展中的 document 是否正确,并且在扩展中的断点(以及页面上的控制台)中检查时 document.domain 会给出正确的结果。
我尝试检查 jQuery._data( jQuery(document)[0]).events["touchmove"](和 "mousewheel"、"mousemove"、"scroll")并且它在控制台中工作,但如果我在断点延期。当我进一步检查时, jQuery._data( jQuery(document)[0]) 给出以下信息:
在控制台中:
1 2 3 4
| Object
events: Object
handle: function (e)
__proto__: Object |
在断点处:
1 2
| Object
__proto__: Object |
我已经尝试了一些其他的东西(例如,jQuery 是可访问和工作的,等等)。
- 您是否尝试关闭您在内容脚本中添加的事件侦听器,或者页面脚本中已经存在的事件侦听器(即是网页的一部分)?听起来您要关闭的事件在页面脚本中。
-
我正在尝试关闭页面脚本中已经存在的事件侦听器(即是网页的一部分)。
您正在尝试执行 $(document).off() 以删除由页面脚本(网页中已存在的脚本;即不是您的内容脚本)添加的 jQuery 事件处理程序。 jQuery 将哪些事件处理程序存储在正在使用的 jQuery 实例内部的数据结构中。您的内容脚本与页面脚本的上下文/范围不同。因此,当您在内容脚本的上下文中执行 $(document).off() 时,该 jQuery 实例不知道页面脚本添加的任何偶数处理程序,并且无法删除它们。
为了使您的 $(document).off() 生效,它必须在页面脚本上下文中运行。在页面脚本上下文中执行代码的最常见方法是创建 元素并将其插入页面的 DOM。
您可以将代码更改为:
1 2 3 4 5 6 7 8 9
| chrome.runtime.onMessage.addListener(
function(request, sender, sendResponse) {
if( request.message ==="clicked_browser_action" ) {
let newScript = document.createElement('script');
newScript.innerHTML='$(document).off("touchmove mousewheel mousemove scroll");';
document.head.appendChild(newScript);
}
}
); |
添加的脚本在页面上下文中运行,因为它现在是 DOM 中的 元素。浏览器识别出添加了一个 元素,并在插入它的脚本不再处理时对其进行评估(执行包含的代码)。对于添加到 DOM 的任何其他元素,它的作用基本相同。因为它是页面的一部分,所以 内的代码在页面脚本上下文/范围内运行。
虽然上述方法有效,尤其是对于此类短代码,但我更喜欢创建 元素以在页面上下文中执行代码的方法是使用我编写的名为 executeInPage() 的函数。您可以在我对"从浏览器扩展调用网页 JavaScript 方法"的回答中找到该函数。
- 惊人!这似乎确实有效,我很快就会将其标记为答案(尽管您可能想要编辑 $(document) 行中的引号)。您可以使我对插入的脚本实际上如何运行感到困惑(确实如此,但是为什么?)...您能澄清一下吗?
-
固定的。我一直在做太多的 MarkDown 编辑。它会运行,因为它是页面中的 元素。浏览器识别出添加了一个 元素,并在插入它的脚本不再处理时对其进行评估(执行它)。对于添加到 DOM 的任何其他元素,它的作用基本相同。
-
你太棒了 Makyen,非常感谢,这让我发疯了。我不得不说我怀疑这将是一个范围的事情,但不知道解决方案,优点是我也刚刚学到了一些关于附加脚本的东西......
-
我很高兴我能提供帮助。请注意,为了执行,必须通过编程方法创建 元素,而不是通过为 "doFoo();" 添加 HTML 文本。您可以将代码作为文本添加到 (例如 doFoo(); 部分),但您不能使用任何调整/插入 HTML 文本的方法(例如 innerHTML、insertAdjacentHTML())添加 本身。这样做是出于安全原因。
-
仅供参考:那个博客页面(