You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Chrome扩展:如何根据点击链接动态更新上下文菜单(替代menus.onShown)

Chrome Workarounds for Dynamic Context Menu Item Text (Alternative to Firefox's menus.onShown)

Great question! You're right that Chrome doesn't currently support the menus.onShown API that Firefox offers for dynamically updating context menu items based on the target link's URL or text. But there are a couple of solid workarounds to achieve the same effect.

Method 1: Update Menu Item Text on Context Menu Trigger

The core idea here is to listen for the contextmenu event in a content script, grab the target link's details, and send that data to your background script to update the menu item's title right before the menu appears.

Step 1: Configure Manifest Permissions

First, make sure your manifest.json includes the necessary permissions for context menus, content scripts, and scripting:

{
  "manifest_version": 3,
  "name": "Dynamic Link Context Menu",
  "version": "1.0",
  "permissions": ["contextMenus", "activeTab", "scripting"],
  "background": {
    "service_worker": "background.js"
  }
}

Step 2: Initialize Menu in Background Script

Create a base context menu item when your extension installs:

// background.js
chrome.runtime.onInstalled.addListener(() => {
  chrome.contextMenus.create({
    id: "dynamic-link-action",
    title: "Default Action",
    contexts: ["link"] // Only show on links
  });
});

// Listen for messages from content scripts to update the menu
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === "updateMenuTitle") {
    chrome.contextMenus.update("dynamic-link-action", {
      title: `Open "${message.linkText}" (${message.linkUrl.slice(0, 50)}...)`
    });
  }
});

Step 3: Trigger Update from Content Script

Add a content script that listens for the right-click event, checks if the target is a link, and sends the link's details to the background:

// content-script.js
document.addEventListener("contextmenu", (event) => {
  const targetLink = event.target.closest("a");
  if (targetLink?.href) {
    chrome.runtime.sendMessage({
      type: "updateMenuTitle",
      linkText: targetLink.textContent.trim(),
      linkUrl: targetLink.href
    });
  }
});

Notes for This Method

  • This approach works in most cases because the contextmenu event fires just before the menu is displayed, giving the background script time to update the title.
  • Be mindful of edge cases: if a user right-clicks extremely quickly, there might be a tiny delay, but this is rare in practice.
  • Use closest("a") instead of checking event.target.tagName directly to handle links with nested elements (e.g., <a><span>Link Text</span></a>).

Method 2: Dynamically Create/Delete Menu Items

If you need more flexibility, you can delete existing menu items and create new ones tailored to the target link when the user right-clicks.

Example Implementation

Background Script

// background.js
chrome.runtime.onInstalled.addListener(() => {
  // No initial menu needed—we'll create it dynamically
});

// Handle menu clicks
chrome.contextMenus.onClicked.addListener((info, tab) => {
  if (info.menuItemId === "dynamic-link-custom") {
    // Do something with the link, e.g., open in new tab
    chrome.tabs.create({ url: info.linkUrl });
  }
});

// Listen for requests to create the dynamic menu
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  if (message.type === "createDynamicMenu") {
    // First remove any existing dynamic menu item
    chrome.contextMenus.remove("dynamic-link-custom", () => {
      // Ignore errors if the item doesn't exist
      chrome.contextMenus.create({
        id: "dynamic-link-custom",
        title: `Open Link: ${message.linkText}`,
        contexts: ["link"],
        linkUrl: message.linkUrl
      });
    });
  }
});

Content Script

Same as Method 1, but send a "createDynamicMenu" message instead:

// content-script.js
document.addEventListener("contextmenu", (event) => {
  const targetLink = event.target.closest("a");
  if (targetLink?.href) {
    chrome.runtime.sendMessage({
      type: "createDynamicMenu",
      linkText: targetLink.textContent.trim(),
      linkUrl: targetLink.href
    });
  }
});

Notes for This Method

  • This avoids any race conditions with updating existing items, as you're creating a fresh item each time.
  • If your extension has multiple context menu items, use chrome.contextMenus.remove with specific IDs instead of removeAll to avoid deleting unrelated items.

Key Considerations

  • Permissions: Ensure you have the contextMenus permission, plus activeTab or <all_urls> to inject content scripts into the pages where you want the dynamic menu to work.
  • Manifest V3 vs V2: The examples above use Manifest V3 (the current standard for Chrome extensions). If you're still on V2, adjust the background script syntax (replace service workers with background pages) and content script injection methods.

内容的提问来源于stack exchange,提问作者Alexey Romanov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:39:43