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 doSomethingAsync();

  // 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 語法

引數

監聽器

此事件發生時呼叫的函式。該函式會傳遞以下引數:

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);
});

擴充套件程式示例

瀏覽器相容性