menus.create()

使用定义了菜单项属性的对象来创建一个菜单项。

与其他异步函数不同,这个函数不返回 Promise,而是使用一个可选的回调函数来通信成功或失败。这是因为它的返回值是新项的 ID。

为了与其他浏览器兼容,Firefox 在 contextMenus 命名空间和 menus 命名空间中都提供了此方法。但是,使用 contextMenus 命名空间无法创建工具菜单项 (contexts: ["tools_menu"])。

在持久化和非持久化扩展中创建菜单

你创建菜单项的方式取决于你的扩展是否使用

  • 非持久化后台页面(事件页面),在这种情况下,菜单会在浏览器和扩展重启后仍然存在。你需要从 runtime.onInstalled 监听器中调用 menus.create(带有一个菜单特定的 ID)。这可以避免在页面重启时重复尝试创建菜单项,这在顶层调用时会发生。
  • 持久化后台页面
    • 在 Chrome 中,持久化后台页面的菜单项是持久化的。在 runtime.onInstalled 监听器中创建你的菜单。
    • 在 Firefox 中,持久化后台页面的菜单项永远不会持久化。在顶层无条件调用 menus.create 来注册菜单项。

有关更多信息,请参阅背景脚本页面上的 初始化扩展 和 Extension Workshop 上的 事件驱动的背景脚本

语法

js
browser.menus.create(
  createProperties, // object
  () => {/* … */}   // optional function
)

参数

createProperties

object。新菜单项的属性。

checked 可选

boolean。复选框或单选按钮项的初始状态:true 表示选中,false 表示未选中。在给定的一组单选按钮项中,一次只能选中一个单选按钮项。

command 可选

string。描述用户点击该项时应执行的操作的字符串。可识别的值包括:

  • "_execute_browser_action":模拟点击扩展的浏览器操作,如果它有弹出窗口则打开(仅限 Manifest V2)
  • "_execute_action":模拟点击扩展的操作,如果它有弹出窗口则打开(仅限 Manifest V3)
  • "_execute_page_action":模拟点击扩展的页面操作,如果它有弹出窗口则打开
  • "_execute_sidebar_action":打开扩展的侧边栏

有关详细信息,请参阅 manifest.json 键 commands 中特殊快捷方式的文档。

当指定了可识别值之一时,点击该项不会触发 menus.onClicked 事件;相反,会触发默认操作,例如打开弹出窗口。否则,点击该项将触发 menus.onClicked,并且可以使用该事件来实现回退行为。

contexts 可选

array of menus.ContextType。将显示此菜单项的上下文数组。如果省略此选项

  • 如果项的父项设置了上下文,则此项将继承其父项的上下文
  • 否则,该项将被赋予一个上下文数组 ["page"]。
documentUrlPatterns 可选

array of string。允许你将该项限制为仅应用于 URL 与给定 匹配模式 之一匹配的文档。这同样适用于框架。

enabled 可选

boolean。此菜单项是启用还是禁用。默认为 true

icons 可选

object。一个或多个要显示在该项旁边的自定义图标。自定义图标只能为出现在子菜单中的项设置。此属性是一个对象,其中包含每个提供的图标的一个属性:属性的名称应包含图标的像素大小,路径是相对于扩展根目录的图标路径。浏览器会尝试选择一个 16x16 像素的图标用于正常显示,或一个 32x32 像素的图标用于高密度显示。为避免任何缩放,你可以这样指定图标:

js
browser.menus.create({
  icons: {
    16: "path/to/geo-16.png",
    32: "path/to/geo-32.png",
  },
});

或者,你也可以指定一个单一的 SVG 图标,它会被适当地缩放

js
browser.menus.create({
  icons: {
    16: "path/to/geo.svg",
  },
});

注意: 顶层菜单项使用 manifest 中指定的 图标,而不是此键中指定的图标。

id 可选

string。要分配给此项的唯一 ID。对于 Manifest V2 中的非持久化 后台(事件)页面 和 Manifest V3 是必需的。不能与此扩展的其他 ID 相同。

onclick 可选

function。点击菜单项时调用的函数。事件页面不能使用此函数:相反,它们应该为 menus.onClicked 注册一个监听器。

parentId 可选

integerstring。父菜单项的 ID;这使该项成为先前添加的项的子项。注意:如果你创建了多个菜单项,那么这些项将被放置在一个子菜单中。子菜单的父项将以扩展的名称进行标记。

targetUrlPatterns 可选

array of string。与 documentUrlPatterns 类似,但允许你根据 anchor 标签的 href 以及 img/audio/video 标签的 src 属性进行过滤。此参数支持任何 URL 方案,即使是通常不允许在匹配模式中使用的方案。

title 可选

string。将在项中显示的文本。除非 type 为 "separator",否则为必需。

你可以在字符串中使用 %s。如果你在菜单项中使用此项,并且当菜单显示时页面上选中了一些文本,那么选中的文本将被插入到标题中。例如,如果 title 是 "Translate '%s' to Pig Latin",用户选择了单词 "cool",然后激活了菜单,那么菜单项的标题将是:"Translate 'cool' to Pig Latin"。

如果标题包含一个 ampersand "&",则下一个字符将被用作该项的访问键,ampersand 将不会显示。例外情况是

  • 如果下一个字符也是一个 ampersand:那么将显示一个 ampersand,并且不会设置访问键。实际上,"&&" 用于显示单个 ampersand。
  • 如果下一个字符是插值指令 "%s":那么 ampersand 将不会显示,也不会设置访问键。
  • 如果 ampersand 是标题中的最后一个字符:那么 ampersand 将不会显示,也不会设置访问键。

只有一个 ampersand 会被用来设置访问键:后续的 ampersands 将不会显示,但也不会设置键。所以 "&A and &B" 将显示为 "A and B" 并将 "A" 设置为访问键。

在某些 Firefox 的本地化版本(日语和中文)中,访问键会用括号括起来并附加到菜单标签上,除非菜单标题本身已经以访问键结尾(例如 "toolkit(&K)")。有关更多详细信息,请参阅 Firefox bug 1647373

type 可选

menus.ItemType。菜单项的类型:"normal", "checkbox", "radio", "separator"。默认为 "normal"。

viewTypes 可选

extension.ViewType。将显示菜单项的视图类型列表。默认为任何视图,包括那些没有 viewType 的视图。

visible 可选

boolean。该项是否在菜单中显示。默认为 true

callback 可选

function。在项创建后调用。如果创建项时有任何问题,详细信息将在 runtime.lastError 中提供。

返回值

integerstring。新创建项的 ID

示例

此示例创建一个上下文菜单项,该菜单项在用户在页面上选择了某些文本时显示。它只是将选定的文本记录到控制台

js
browser.menus.create({
  id: "log-selection",
  title: "Log '%s' to the console",
  contexts: ["selection"],
});

browser.menus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "log-selection") {
    console.log(info.selectionText);
  }
});

此示例添加了两个单选按钮项,您可以使用它们来选择是将绿色还是蓝色边框应用于页面。请注意,此示例需要 activeTab 权限

js
function onCreated() {
  if (browser.runtime.lastError) {
    console.log("error creating item:", browser.runtime.lastError);
  } else {
    console.log("item created successfully");
  }
}

browser.menus.create(
  {
    id: "radio-green",
    type: "radio",
    title: "Make it green",
    contexts: ["all"],
    checked: false,
  },
  onCreated,
);

browser.menus.create(
  {
    id: "radio-blue",
    type: "radio",
    title: "Make it blue",
    contexts: ["all"],
    checked: false,
  },
  onCreated,
);

let makeItBlue = 'document.body.style.border = "5px solid blue"';
let makeItGreen = 'document.body.style.border = "5px solid green"';

browser.menus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "radio-blue") {
    browser.tabs.executeScript(tab.id, {
      code: makeItBlue,
    });
  } else if (info.menuItemId === "radio-green") {
    browser.tabs.executeScript(tab.id, {
      code: makeItGreen,
    });
  }
});

扩展程序示例

浏览器兼容性

注意: 此 API 基于 Chromium 的 chrome.contextMenus API。本文档源自 Chromium 代码中的 context_menus.json