为什么 chrome.contextMenus 创建多个条目?

Why does chrome.contextMenus create multiple entries?

我正在使用 chrome.contextMenus.create 函数在我的 Chrome 扩展程序中创建上下文菜单。但它创造了额外的选择。

我在我的 manifest.json 文件中授予了权限,在我的 background.js 文件中添加了此功能并将其添加到我的 manifest.json 文件中。

为什么会这样?

function getword(info,tab) {
  console.log("Word " + info.selectionText + " was clicked.");
  chrome.tabs.create({  
    url: "http://www.google.com/search?q=" + info.selectionText,
  });           
}
chrome.contextMenus.create({
  title: "Search: %s", 
  contexts:["selection"], 
  onclick: getword,
});

您的后台代码将执行多次 - 至少在每次浏览器启动/扩展程序重新加载时执行,最多在每次 Event page ("persistent": false) 唤醒时执行。

chrome.contextMenus.create 做它在锡罐上所说的 - 创建一个新条目。每次都是运行。这很好,因为通常您希望在扩展程序 运行 时设置所有内容,但 上下文菜单条目实际上 在扩展程序重新加载之间保持 - 所以他们不断堆积。

这里有两种方法:

  1. 为您的上下文条目分配一个 ID(这是一个任意字符串);在这种情况下,使用相同的 ID 再次调用 create 覆盖它 引发错误,而不是创建新的错误。

    chrome.contextMenus.create({
      title: "Search: %s",
      id: "search",
      contexts:["selection"], 
      onclick: getword,
    });
    

    不管怎样,这对以后操作/引用条目很有用。

  2. 在调用 create:

    之前擦除上下文菜单条目
    chrome.contextMenus.removeAll(function() {
      chrome.contextMenus.create({
        // ...
      });
    });
    

    这似乎是多余的,但这是确保 "old" 以前版本的扩展的上下文菜单条目不会留下的最简单方法。

当然,你可以把两者结合起来。


进一步说明:

  • 如果您实际使用的是"persistent": false事件页面,请注意不允许使用onclick属性,因为它会因扩展卸载而失效。更稳健的方法是使用 chrome.contextMenus.onClicked 事件 - 菜单项的 ID 将传递给它以区分选项。

  • 由于您很少需要更新上下文菜单项,因此最好将它们隐藏在相应的事件中,chrome.runtime.onStartup and/or chrome.runtime.onInstalled

    但是,请注意,在非常罕见的情况下,您可能会遇到错误:

    1. 扩展已安装但被禁用。
    2. 禁用时进行更新。
    3. 此更新实际上应该更改其中任一事件中的上下文菜单。
    4. 然后,扩展程序再次启用。

    在那种情况下,两个事件都不会触发。这是一个bug.