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

9
我正在使用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,
});

enter image description here


1
请提供您用于创建父子上下文菜单的实际代码,您是在什么时候调用了 chrome.contextMenus.create?我猜您没有将函数包装到类似于 chrome.runtime.onStartup 事件中,这会导致每次激活扩展时都会调用该函数。 - Haibara Ai
1个回答

16

您的背景代码将会执行多次——至少在每次浏览器启动/扩展重新加载时,最多每当一个事件页面("persistent": false)唤醒时。

chrome.contextMenus.create做了它所说的——创建一个新的项。每次都是如此。这本来没什么问题,因为通常当你的扩展程序运行时,你想要设置好一切,但是上下文菜单项实际上会在扩展程序重新加载时保留——因此它们会不断堆积。

这里有两种方法:

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

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

    无论如何,这仍然是一个有用的方式,以后可以操纵/引用该条目。

  2. 在调用create之前,请清除您的上下文菜单条目:

  3. chrome.contextMenus.removeAll(function() {
      chrome.contextMenus.create({
        // ...
      });
    });
    

    这似乎有些多余,但这是确保你的扩展中“旧”的上下文菜单条目不会保留的最简单方法。

当然,你也可以将两者结合在一起。


还有几点需要注意:

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

  • 由于你很少需要更新上下文菜单项,所以最好将它们隐藏在相应的事件中,例如chrome.runtime.onStartup和/或chrome.runtime.onInstalled

    但是,请注意,在非常罕见的情况下,你会遇到一个错误组合:

    1. 安装了但未启用扩展程序。
    2. 在禁用扩展时发生更新。
    3. 此更新实际上应更改这些事件之一中的上下文菜单。
    4. 然后,再次启用扩展。

    在这些情况下,没有事件会触发。这是一个错误


2
老兄谢谢,我加了 "chrome.contextMenus.removeAll(function()" 和 "id",现在它正常工作了。 - user4991434

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接