【问题标题】:in chrome extensions how to trigger an event on deactivation?在 chrome 扩展中如何触发停用事件?
【发布时间】:2016-05-09 11:11:45
【问题描述】:

我有一个 chrome 扩展,它通过内容脚本注入一些 DOM 事件侦听器。如果用户停用插件,我想从 DOM 中删除这些事件侦听器,有没有办法这样做?

【问题讨论】:

  • 你试过removeEventListener()吗?

标签: javascript google-chrome dom google-chrome-extension event-handling


【解决方案1】:
  1. onDisabled 在应用或扩展程序被禁用时触发。

    chrome.management.onDisabled.addListener(function callback)
    
  2. EventTarget.removeEventListener() 移除之前注册的事件监听器。

    var div = document.getElementById('div');
    var listener = function (event) {
      /* do something here */
    };
    div.addEventListener('click', listener, false);
    div.removeEventListener('click', listener, false);
    
  3. 我认为你不需要这样做,因为一旦你的扩展被禁用,你的事件监听器将被删除并且不会被注入。

【讨论】:

  • 投反对票,因为chrome.management.onDisabled 肯定不会有帮助。如果扩展程序被禁用或卸载,则不会触发任何事件。
  • 另一个原因是 #3 我不正确:来自已停用扩展程序的内容脚本仍然存在,直到导航发生。
  • @xan 你能澄清一下“chrome.management.onDisabled 肯定不会有帮助。如果扩展被禁用或卸载,不会触发任何事件”?该文档特别将 onDisabled 事件描述为“当应用程序或扩展程序被禁用时触发”。 developer.chrome.com/extensions/management#event-onDisabled
  • @Katie 具体来说,卸载/禁用扩展程序本身时不会生成任何事件。此事件在具有管理权限的其他扩展中触发。
【解决方案2】:

这是一个有趣的问题。它与“孤立”脚本的概念有关。我在附录here 中详细讨论了这些内容。

问题是,一旦脚本与父扩展分离,Chrome API 就会失败。因此,检测这一点并不简单。

有很多可能的方法:

  1. 维护一个open port 到后台页面。如果后台页面不复存在,端口将触发onDisconnected 事件。

    这是一种基于事件的方法 - 您将能够立即做出反应。

    但这有一个重要的缺点:保持一个开放的端口会阻止Event page 卸载。因此,如果您使用非持久性背景页面,这不是最佳选择。

  2. 定期,或者更好 - 在您的处理程序开始时,尝试使用 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);
    
  3. 终于有了a proposal to make a special event for this situation,不过还没实现。

  4. 专门针对updates when the extension is reloaded,您可以使其将脚本注入现有页面并让旧脚本知道它们应该停用;但是,由于您的问题是关于扩展被删除,它没有帮助。

完成困难的部分后,实际删除事件侦听器取决于您添加它们的方式,但应该很简单。

【讨论】:

  • 所以我应该定期运行 chrome API 脚本并将错误捕获为停用触发器?如果我需要立即触发事件,这似乎很费力,所以我的间隔可能是 10 毫秒(插件与视频流有关),根本就没有事件驱动的通知方式吗?
  • 就像我说的——虽然有提案,但没有事件;您可以使用端口的onDisconnected 事件,但它会保持后台页面加载。我唯一可以建议的是,如果您不在乎您的扩展程序在其背景消失后的一段时间内仍然处于活动状态,请进行速率限制检查。
  • 哦,没关系,第一个解决方案似乎很合适,通过维护一个开放端口来检测 onDisconnected 事件,我想我可以在断开连接时运行 API 脚本,如果它抛出错误然后删除侦听器(确保断开连接确实来自停用)。
  • 只要您使用持久背景页面,就没有任何缺点。
  • 所以我需要 manifest.json 中的 "persistent" : true 吗?没关系,我猜。谢谢会给出最好的答案。
猜你喜欢
  • 2014-09-25
  • 2013-09-11
  • 2016-07-10
  • 1970-01-01
  • 2015-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多