如何同时在普通与隐身窗口启用Chrome扩展右键菜单?
解决扩展右键菜单在普通/隐身窗口同时显示的问题
这个问题的核心是你当前的代码只在**单个上下文(普通或隐身)**加载时执行一次,而Chrome的非持久后台脚本(事件页面)在普通和隐身模式下是独立运行的实例,导致菜单只在其中一个窗口生效。咱们来一步步修复:
问题分析
你原代码的逻辑是判断当前上下文是否为隐身模式,然后创建对应ID的菜单,但这段代码只在后台脚本加载时执行一次。如果隐身窗口先打开,后台的隐身实例会创建隐身菜单,而普通窗口的后台实例可能没被触发加载,自然不会生成普通窗口的菜单;关闭隐身窗口后,普通窗口的后台实例才会激活,菜单才会显示。
修复方案
1. 确保扩展允许在隐身模式运行
先去扩展管理页面(chrome://extensions/)找到你的扩展,点击「详细信息」,开启「允许在隐身模式下运行」——这是基础前提,否则隐身窗口根本不会加载你的扩展。
2. 修改代码,绑定到合适的事件
把菜单创建逻辑放到chrome.runtime.onInstalled和chrome.runtime.onStartup事件里,确保扩展安装/更新、浏览器启动时,普通和隐身的后台实例都会执行菜单创建操作。同时优化异步逻辑,避免移除菜单失败导致创建中断:
// 封装菜单创建逻辑 function setupContextMenu() { // 普通/隐身上下文用不同ID(如果需要区分菜单的话) const menuId = chrome.extension.inIncognitoContext ? 'changelogIncognito' : 'changelog'; const menuTitle = chrome.extension.inIncognitoContext ? 'View Change Log (Incognito)' : 'View Change Log'; // 先移除当前上下文的目标菜单(忽略移除失败的情况,比如菜单还没创建) chrome.contextMenus.remove(menuId, () => { chrome.contextMenus.create({ id: menuId, title: menuTitle, contexts: ["browser_action"] }); }); } // 扩展安装或更新时执行 chrome.runtime.onInstalled.addListener(setupContextMenu); // 浏览器启动时执行 chrome.runtime.onStartup.addListener(setupContextMenu);
如果不需要区分普通和隐身的菜单样式,也可以简化成统一ID,因为Chrome会自动隔离普通和隐身窗口的菜单实例:
function setupContextMenu() { // 先清空当前上下文的所有菜单,再创建 chrome.contextMenus.removeAll(() => { chrome.contextMenus.create({ id: 'changelog', title: 'View Change Log', contexts: ["browser_action"] }); }); } chrome.runtime.onInstalled.addListener(setupContextMenu); chrome.runtime.onStartup.addListener(setupContextMenu);
这样修改后,不管是普通窗口还是隐身窗口,只要扩展加载,就会各自创建对应的右键菜单,不会互相干扰啦。
内容的提问来源于stack exchange,提问作者Kruu Kruu
相关产品推荐
相关产品推荐

