menus.onShown

当浏览器显示菜单时触发。

扩展可以使用此事件来更新其菜单项,使用仅在菜单显示后才能获得的信息。通常,扩展将在其 onShown 处理程序中找出更新内容,然后调用 menus.refresh() 来更新菜单本身。

处理程序可以添加、删除或更新菜单项。

例如,menu-labelled-open 示例扩展添加了一个菜单项,当用户点击链接时显示,当点击时,只需打开链接。它使用 onShownrefresh() 用链接的主机名标注菜单项,以便用户在点击之前可以轻松看到将要访问的地址。

注意,扩展不应在调用 refresh() 之前花费太多时间,否则更新将对用户可见。

处理程序会接收到一些关于菜单及其内容的信息,以及来自页面的一些信息(如链接和/或选定文本)。要访问来自页面的信息,你的扩展必须具有对它的 主机权限

如果 onShown 处理程序调用了任何异步 API,则菜单可能在处理程序恢复执行之前已关闭。因此,如果处理程序调用了任何异步 API,它应该在更新菜单之前检查菜单是否仍在显示。例如

js
let lastMenuInstanceId = 0;
let nextMenuInstanceId = 1;

browser.menus.onShown.addListener(async (info, tab) => {
  let menuInstanceId = nextMenuInstanceId++;
  lastMenuInstanceId = menuInstanceId;

  // Call an async function
  await /* the function to call */ ;

  // After completing the async operation, check whether the menu is still shown.
  if (menuInstanceId !== lastMenuInstanceId) {
    return; // Menu was closed and shown again.
  }
  // Now use menus.create/update + menus.refresh.
});

browser.menus.onHidden.addListener(() => {
  lastMenuInstanceId = 0;
});

注意,可以同步调用 menus API 函数,在这种情况下,不需要执行此检查

js
browser.menus.onShown.addListener(async (info, tab) => {
  browser.menus.update(menuId /*, …*/);
  // Note: Not waiting for returned promise.
  browser.menus.refresh();
});

但是,如果你异步调用这些 API,则必须执行此检查

js
browser.menus.onShown.addListener(async (info, tab) => {
  let menuInstanceId = nextMenuInstanceId++;
  lastMenuInstanceId = menuInstanceId;

  await browser.menus.update(menuId /*, …*/);
  // must now perform the check
  if (menuInstanceId !== lastMenuInstanceId) {
    return;
  }
  browser.menus.refresh();
});

Firefox 通过 contextMenus 命名空间和 menus 命名空间提供此事件。

语法

js
browser.menus.onShown.addListener(listener)
browser.menus.onShown.removeListener(listener)
browser.menus.onShown.hasListener(listener)

事件具有三个函数

addListener(listener)

为该事件添加监听器。

removeListener(listener)

停止监听该事件。listener 参数是要移除的监听器。

hasListener(listener)

检查 listener 是否已为该事件注册。如果正在监听,则返回 true,否则返回 false

addListener 语法

参数

listener

当该事件发生时调用的函数。该函数传递以下参数

info

Object。这与 menus.OnClickData 对象相同,只是它包含两个额外的属性

  • contexts:一个包含所有适用于该菜单的 contexts 的数组。
  • menuIds:一个包含所有属于该扩展并在该菜单中显示的菜单项 ID 的数组。

menus.OnClickData 相比,info 对象还省略了 menuItemIdmodifiers 属性,因为当然,只有在选择了菜单项后才能获得这些属性。

始终提供 contextsmenuIdsframeIdeditable 属性。info 中的所有其他属性仅在扩展具有对该页面的 主机权限 时才会提供。

tab

tabs.Tab。发生点击的选项卡的详细信息。如果点击没有发生在选项卡中或选项卡上,则此参数将缺失。

示例

此示例监听上下文菜单在链接上显示,然后用链接的主机名更新 openLabelledId 菜单项

js
function updateMenuItem(linkHostname) {
  browser.menus.update(openLabelledId, {
    title: `Open (${linkHostname})`,
  });
  browser.menus.refresh();
}

browser.menus.onShown.addListener((info) => {
  if (!info.linkUrl) {
    return;
  }
  let linkElement = document.createElement("a");
  linkElement.href = info.linkUrl;
  updateMenuItem(linkElement.hostname);
});

示例扩展

浏览器兼容性

BCD 表仅在浏览器中加载