在 chrome 扩展中如何在停用时触发事件?

in chrome extensions how to trigger an event on deactivation?

我有一个 chrome 扩展,它通过内容脚本注入一些 DOM 事件侦听器。我想在用户停用插件的情况下从 DOM 中删除那些事件侦听器,是否有这样做的方法?

  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. 我认为你不需要这样做,因为一旦你的扩展被禁用,你的事件监听器将被删除并且不会被注入。

这是一个有趣的问题。它与 "orphaned" 脚本的概念有关。我在附录 here.

中详细讨论了那些

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

有许多可能的方法:

  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,你可以让它在现有页面中注入脚本,让旧脚本知道它们应该停用;但是,由于您的问题是有关扩展被删除的问题,因此没有帮助。

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