如何在 Chrome 扩展中需要时启用和禁用事件侦听器?

How do I enable and disable an event listener when wanted in a Chrome Extension?

我的 background.js 检测到选项卡焦点的变化。这是它的代码:

chrome.storage.sync.get("tab_focus_change",function(val){
    if(val.tab_focus_change===false)return;
    var activeTabId, lastUrl;

    function getTabInfo(tabId) {
      chrome.tabs.get(tabId, function(tab) {
        if(lastUrl != tab.url)
          lastUrl=tab.url;
          log('The focused tab changed to: <a href="'+tab.url+'">'+tab.url+'</a>');
      });
    }

    chrome.tabs.onActivated.addListener(function(activeInfo) {
      getTabInfo(activeTabId = activeInfo.tabId);
    });

    chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
      if(activeTabId == tabId) {
        getTabInfo(tabId);
      }
    });
});

如您所见,它首先检查 tab_focus_change 是否允许检测选项卡焦点更改。只有当它允许时(值应该是 truefalse),它才会检测到。

我还有一个选项页面,允许您更改 tab_focus_change 是真还是假。选项页面完美运行(我测试过)。出错的地方在于,虽然它已经更新了值,但它会继续跟踪选项卡更改或者它一直不跟踪选项卡更改 - 以更新之前为准。

我注意到,尽管值发生变化,但无论是否跟踪它都不会更新,因为我正在使用事件处理程序。我设置一次,它就开始永远工作(当然直到扩展名是 refreshed/removed)!因此将其设置为 false 不会取消设置处理程序,将其设置为 true 不会启动处理程序。

我想知道如何在应该(取消)设置处理程序时(取消)设置它们。

这是我的扩展中文件的目录列表:

manifest.json // Extension manifest

popup.html // Popup page

options.html // Options page
options.js // Script for options page

background.js // background script

content.js // content script
content.css // content styles

html2canvas.min.js // Just an external library, shouldn't matter too much

我可以将代码添加到我的任何 HTML 或 JS 文件中(只要您说出要放置哪个代码)。

如果事件侦听器是否跟踪更改,我将如何更新?

此外,如果您需要更多详细信息,请在下面评论,我会尽力添加。

使用 a) removeListener 方法,b) chrome.storage.onChanged 事件,以及 c) 在 addListener 范围内或全局声明的命名函数:

const KEY = 'tab_focus_change';

chrome.storage.sync.get(KEY, data => {
  let activeTabId, lastUrl;
  toggleListeners(data[KEY]);
  chrome.storage.onChanged.addListener(changes => {
    if (changes[KEY]) {
      toggleListeners(changes[KEY].newValue);
    }
  });
  function toggleListeners(enable = true) {
    const method = enable ? 'addListener' : 'removeListener';
    chrome.tabs.onActivated[method](onActivated);
    chrome.tabs.onUpdated[method](onUpdated);
  }
  function onActivated(activeInfo) {
    getTabInfo(activeTabId = activeInfo.tabId);
  }
  function onUpdated(tabId, changeInfo, tab) {
    if (activeTabId == tabId) {
      getTabInfo(tabId);
    }
  }
  function getTabInfo(tabId) {
    // console.log(tabId);
  }
});