3

我正在开发一个简单的链接共享扩展(插板、可读性、美味等),并且有一个关于如何正确处理上下文菜单项的问题。在我的非持久性背景页面中,我调用chrome.contextMenus.createchrome.contextMenus.onClicked.addListener设置/响应上下文菜单。

上下文菜单条目按预期工作。但是后台页面显示以下错误(在它启动之后和我使用该条目之前):

contextMenus.create: Cannot create item with duplicate id id_share_link at chrome-extension://.../share.js:52:30 lastError:29 set  

这让我意识到,我在任何时候都不会删除项目或监听器。对javascript和扩展知之甚少,我想知道我是否正确地做所有事情。我假设每次调用后台页面时都会重新执行此顶级代码。所以会有多余的调用来创建和 addListener (因此我看到的错误被记录了)。

我显然无法响应挂起进行清理,因为需要存在这些调用才能唤醒后台脚本。

我应该以不同的方式处理事情吗?

4

3 回答 3

5

您可以通过以下两种方式之一处理它:

  1. 您可以在安装时添加上下文菜单和侦听器:

    chrome.runtime.onInstalled.addListener(function() {
      /* Add context menu and listener */
    });
    
  2. 您可以删除上下文菜单和侦听器,然后在每次调用文件时重新添加。

于 2013-08-23T04:30:20.257 回答
5

如果您想使用事件页面,即非持久性背景页面,正如您所称的那样,您应该通过contextMenus.create在事件处理程序中注册一个上下文菜单runtime.onInstalled,因为这些上下文菜单注册无论如何都是“持久的”。

contextMenus.onClicked但是,每次重新加载事件页面时,您都必须为事件添加侦听器函数,因为您希望侦听该事件的注册仍然存在,而处理程序回调本身则不会。所以一般不要调用contextMenus.onClicked.addListenerfrom runtime.onInstalled,而是从顶层或其他代码调用,保证每次加载事件页面时都会执行。[ 1 ]

于 2013-10-25T00:16:50.610 回答
0

[解决方案可能不再是这种情况,请阅读评论]

runtime.onInstalled如果您禁用/启用您的扩展程序,则不会触发。
我的解决方案是始终添加菜单项并吞下错误:

'use strict';

{

  let seqId = 0;

  const createMenuLinkEntry = (title, tab2url) => {

    const id = (++seqId).toString();

    chrome.contextMenus.create({
      id: id,
      title: title,
      contexts: ['browser_action'],
    }, () => {

      const err = chrome.runtime.lastError;
      if(err) {
        console.warn('Context menu error ignored:', err);
      }

    });

  };

  createMenuLinkEntry('Go to Google', (tab) => 'https://google.com');
  createMenuLinkEntry('Go to GitHub', (tab) => 'https://github.com');

} // namespace
于 2017-03-17T17:42:08.850 回答