【发布时间】:2016-05-09 11:11:45
【问题描述】:
我有一个 chrome 扩展,它通过内容脚本注入一些 DOM 事件侦听器。如果用户停用插件,我想从 DOM 中删除这些事件侦听器,有没有办法这样做?
【问题讨论】:
-
你试过
removeEventListener()吗?
标签: javascript google-chrome dom google-chrome-extension event-handling
我有一个 chrome 扩展,它通过内容脚本注入一些 DOM 事件侦听器。如果用户停用插件,我想从 DOM 中删除这些事件侦听器,有没有办法这样做?
【问题讨论】:
removeEventListener()吗?
标签: javascript google-chrome dom google-chrome-extension event-handling
onDisabled 在应用或扩展程序被禁用时触发。
chrome.management.onDisabled.addListener(function callback)
EventTarget.removeEventListener() 移除之前注册的事件监听器。
var div = document.getElementById('div');
var listener = function (event) {
/* do something here */
};
div.addEventListener('click', listener, false);
div.removeEventListener('click', listener, false);
我认为你不需要这样做,因为一旦你的扩展被禁用,你的事件监听器将被删除并且不会被注入。
【讨论】:
chrome.management.onDisabled 肯定不会有帮助。如果扩展程序被禁用或卸载,则不会触发任何事件。
这是一个有趣的问题。它与“孤立”脚本的概念有关。我在附录here 中详细讨论了这些内容。
问题是,一旦脚本与父扩展分离,Chrome API 就会失败。因此,检测这一点并不简单。
有很多可能的方法:
维护一个open port 到后台页面。如果后台页面不复存在,端口将触发onDisconnected 事件。
这是一种基于事件的方法 - 您将能够立即做出反应。
但这有一个重要的缺点:保持一个开放的端口会阻止Event page 卸载。因此,如果您使用非持久性背景页面,这不是最佳选择。
定期,或者更好 - 在您的处理程序开始时,尝试使用 Chrome API 做一些事情。 这将失败,您可以捕获异常并假设扩展是孤立的。
请注意,这几乎是未定义的行为。 Chrome API 的反应方式会随着时间而改变。
function heartbeat(success, failure) {
try {
if(chrome.runtime.getManifest()) {
success();
} else { // will return undefined in an orphaned script
failure();
}
} catch(e) { // currently doesn't happen, but may happen
failure();
}
}
function handler() {
heartbeat(
function(){ // hearbeat success
/* Do stuff */
},
function(){ // hearbeat failure
someEvent.removeListener(handler);
console.log("Goodbye, cruel world!");
}
);
}
someEvent.addListener(handler);
终于有了a proposal to make a special event for this situation,不过还没实现。
专门针对updates when the extension is reloaded,您可以使其将脚本注入现有页面并让旧脚本知道它们应该停用;但是,由于您的问题是关于扩展被删除,它没有帮助。
完成困难的部分后,实际删除事件侦听器取决于您添加它们的方式,但应该很简单。
【讨论】:
onDisconnected 事件,但它会保持后台页面加载。我唯一可以建议的是,如果您不在乎您的扩展程序在其背景消失后的一段时间内仍然处于活动状态,请进行速率限制检查。