在非持久性背景脚本上添加右键菜单项?

15

我正在使用非持久化的后台脚本添加上下文菜单项,使用以下代码:

chrome.contextMenus.create({
  title: 'Get Code',
  id: 'myUniqueIdForThisExtension123',
  contexts: ['all'],
  onclick: onClickHandler
});

function onClickHandler() {}

documentation简单地说明:

分配给此项的唯一ID。对于事件页面是强制性的。不能与此扩展的其他ID相同。

所以我添加了一个唯一的ID,但仍然无法使其工作。在上下文菜单中没有插入任何新内容。

2个回答

37

您说您有一个非持久化的后台页面,因此您应该拥有一个类似于以下内容的 manifest.json 文件:

{
    "manifest_version": 2,

    "name": "My extension",
    "description": "My description",
    "version": "1",
    
    "permissions": ["contextMenus"],
    "background": {
        "persistent": false,
        "scripts": [
            "/background.js"
        ] 
    }
}

现在,由于您有一个非持久的后台页面,您必须使用正确的监听器在需要使用上下文菜单时“唤醒”它。

引用自官方文档(注:此链接指向2014年的文档存档副本,已过时):

使用事件页的最佳实践:

[...]

  1. 如果您正在使用上下文菜单API,请将字符串id参数传递给contextMenus.create,并使用contextMenus.onClicked回调而不是onclick参数到contextMenus.create

所以,简单来说,您的错误是在background.js中使用了onclick参数而不是contextMenus.onClicked.addListener()方法。

解决方案

我已经说过你应该使用onClicked事件,但是我想引用x a's answer的话语:

您应该通过runtime.onInstalled的事件处理程序注册上下文菜单,因为这些上下文菜单注册无论如何都会持久存在。

因此,简单地说,既然创建了上下文菜单后,它们会在您的扩展中持久存在,最佳实践是只在安装(或更新)扩展时定义一次,并在每次加载后台页面时添加监听器。

chrome.runtime.onInstalled.addListener(function() {
    chrome.contextMenus.create({
        title: 'My menu',
        id: 'menu1', // you'll use this in the handler function to identify this context menu item
        contexts: ['all'],
    });
});

chrome.contextMenus.onClicked.addListener(function(info, tab) {
    if (info.menuItemId === "menu1") { // here's where you'll need the ID
        // do something
    }
});

这就是您在事件页中创建上下文菜单所需的内容,如 chrome.contextMenus API 的 documentation page 所示。


1
嗨,背景脚本是非持久的,因此 "background": { "persistent": false, scripts: [] } - Zhianc
@MarcoBonelli 在我的评论中,我说的是后台页面,而你的编辑反映了这一点,但我应该说的是事件页面,因为它是非持久性的。你可能需要重新编辑你最近的编辑,将后台页面更改为事件页面。 - Brian Onn
@BrianOnn 嗯,事件页面是后台页面的一个子类别,这样称呼并不算错。顺便说一下,对于这些小修改,你可以自行应用它们。 - Marco Bonelli

9
修改 Marco Bonelli 所写的内容
如果你想使用一个事件页或所谓的非持久性后台页,你应该在 runtime.onInstalled 的事件处理程序中通过 contextMenus.create 注册一个上下文菜单,因为这些上下文菜单注册会“持久化”。
但是,每次事件页重新加载时,你都需要添加 contextMenus.onClicked 事件的监听函数,因为你监听该事件的“愿望”会持久化,而处理程序本身不会持久化。
因此,为了做到正确™,请在 runtime.onInstalled 中注册你的上下文菜单,但使用从顶层或其他保证每次事件页加载时都会执行的代码设置事件处理程序回调函数。[1]

@Marco,你应该修改你的答案,至少指向这个。 - Xan
@Xan 我实际上正在做它(我已经完成了),谢谢。 - Marco Bonelli

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