Chrome扩展Manifest V3升级后右键翻译弹窗功能异常
问题分析与解决方案
Manifest V3下右键触发翻译弹窗仅能使用1-2次的问题,核心原因是Service Worker自动休眠、消息通信未处理异常、弹窗重复初始化冲突,以下是针对性修复方案:
1. 修复Service Worker休眠导致的菜单监听失效
Manifest V3的background采用Service Worker替代V2的持久化后台页面,闲置后会自动休眠,唤醒后之前注册的上下文菜单可能丢失。需在安装和启动时强制重新注册菜单:
修改Background.js:
const translateSelectionMenuId = 'translate-selection'; // 注册上下文菜单 function createContextMenu() { chrome.contextMenus.removeAll(() => { chrome.contextMenus.create({ id: translateSelectionMenuId, title: '翻译选中文本', contexts: ['selection'] }); }); } // 安装和启动时重新注册菜单 chrome.runtime.onInstalled.addListener(createContextMenu); chrome.runtime.onStartup.addListener(createContextMenu); chrome.contextMenus.onClicked.addListener(function (info, tab) { if (info.menuItemId === translateSelectionMenuId) { chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => { const activeTab = tabs[0]; // 发送消息,失败则自动注入content脚本 chrome.tabs.sendMessage(activeTab.id, { op: "translateSelection", selectedText: info.selectionText, }, (response) => { if (chrome.runtime.lastError) { chrome.scripting.executeScript({ target: { tabId: activeTab.id }, files: ['content.js'] }, () => { chrome.tabs.sendMessage(activeTab.id, { op: "translateSelection", selectedText: info.selectionText, }); }); } }); }); } });
2. 优化弹窗初始化逻辑,避免重复创建Dialog实例
原代码每次触发都重新调用dialog(),导致jQuery Dialog实例冲突、DOM状态混乱。改为仅初始化一次,后续复用实例更新内容:
修改Content.js:
let translateDialogInstance = null; // 保存Dialog实例 chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { if (request.op === "translateSelection") { translateSelection(request.selectedText); sendResponse({ status: 'success' }); // 发送响应避免background端报错 } }); function translateSelection(txt) { let translateDialog = document.getElementById("awsAIExt_translate"); if (!translateDialog) { translateDialog = document.createElement("div"); translateDialog.id = "awsAIExt_translate"; document.body.appendChild(translateDialog); $(translateDialog).load( chrome.runtime.getURL("translate.html") + " #awsAIExt_translate", function () { // 仅初始化一次Dialog translateDialogInstance = $(translateDialog).dialog({ title: "Translate Buddy", width: 700, height: 600, zIndex: 3999, autoOpen: false, // 默认不自动打开 create: function (event, ui) { $("#awsAIExt_translateBtn").click(translate); $("#taskusLogo").attr( "src", chrome.runtime.getURL($("#taskusLogo").attr("src")) ).width(200).height(150); $("#translateBuddyLogo").attr( "src", chrome.runtime.getURL($("#translateBuddyLogo").attr("src")) ).width(200).height(150); }, open: function (event, ui) { if (translatePreferences?.sourceLangCode && translatePreferences?.targetLangCode) { $("#awsAIExt_inputLang").val(translatePreferences.sourceLangCode); $("#awsAIExt_outputLang").val(translatePreferences.targetLangCode); } translate(); }, }); const ele = document.getElementById("ui-id-1"); ele.style.display = "contents"; // 首次加载后设置文本并打开 $("#awsAIExt_inputText").val(txt); translateDialogInstance.dialog("open"); } ); } else { // 已存在弹窗,更新文本并打开 $("#awsAIExt_inputText").val(txt); if (translateDialogInstance) { translateDialogInstance.dialog("open"); translate(); } } }
3. 补充Manifest V3必要权限
确保manifest.json包含所需权限:
{ "manifest_version": 3, "name": "Translate Buddy", "version": "1.0", "background": { "service_worker": "background.js" }, "permissions": ["contextMenus", "scripting", "activeTab"], "web_accessible_resources": [ { "resources": ["translate.html", "*.png", "*.jpg"], "matches": ["<all_urls>"] } ] }
修复说明
- Service Worker部分:通过
onInstalled和onStartup确保菜单每次都正确注册,同时处理sendMessage失败时自动注入content脚本,解决脚本未加载问题。 - Dialog部分:用变量保存Dialog实例,避免重复初始化,仅首次创建时加载模板,后续直接复用实例更新内容。
- 权限部分:Manifest V3需显式声明
scripting权限用于注入脚本,web_accessible_resources确保模板和资源能被网页访问。
内容的提问来源于stack exchange,提问作者Bhagwanta Yeole
相关产品推荐
相关产品推荐

