我正在创建一个 Chrome 字典游戏扩展,该项目的第一部分要求用户能够右键单击一个单词,并且会出现一个侧面板,其中包含该单词的定义(使用本地数据库找到的定义)。 但是,我遇到了一个小问题。用户必须右键单击该单词,然后按“定义”两次,一次拉起侧面板,然后第二次显示定义。 第一次点击时,它会显示: [1]: 第二次点击“WordBank It!”然后它会在侧面板上显示定义: [2]: 我希望它打开侧面板并一键显示定义,显然是为了更好的易用性。我怎样才能这样做呢?这是我的代码文件:
// Copyright 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
function setupContextMenu() {
chrome.contextMenus.create({
id: 'define-word',
title: 'WordBank It!',
contexts: ['selection']
});
}
chrome.runtime.onInstalled.addListener(() => {
setupContextMenu();
});
chrome.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === 'define-word') {
// This will open the panel in all the pages on the current window.
chrome.sidePanel.open({ windowId: tab.windowId });
showDef(info.selectionText);
}
});
function showDef(data) {
// Hide instructions.
document.body.querySelector('#select-a-word').style.display = 'none';
// Show word and definition.
document.body.querySelector('#definition-word').innerText = data.value;
document.body.querySelector('#definition-text').innerText = words[data.value.toLowerCase()]; // websearch
}
<html>
<head>
<title>Dictionary Side Panel</title>
</head>
<body>
<h1>Dictionary</h1>
<hr />
<p id="select-a-word">Select a word to see the definition.</p>
<div>
<h2 id="definition-word"></h2>
<p id="definition-text"></p>
</div>
<script src="service-worker.js"></script>
</body>
</html>
然后显然是manifest.json:
{
"name": "Dictionary side panel",
"version": "0.1",
"manifest_version": 3,
"description": "Provides definitions in the side panel.",
"background": {
"service_worker": "service-worker.js"
},
"icons": {
"128": "tayy.png",
"16": "tayy.png"
},
"side_panel": {
"default_path": "sidepanel.html"
},
"permissions": ["sidePanel", "contextMenus"]
}
我该怎么办?
您需要将 service-worker.js 拆分为两个脚本,因为您有两个不同的上下文。 Service Worker 将注册菜单并处理菜单命令,然后打开侧面板并通过消息传递将所选文本发送到其脚本。当侧面板打开时,将直接收听菜单。
删除
function showDef
并将其移至sidepanel.js
let text;
chrome.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === 'define-word') {
chrome.sidePanel.open({ windowId: tab.windowId });
text = info.selectionText;
}
});
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (msg === 'sidePanelInit') {
sendResponse(text);
}
});
加载 sidepanel.js 而不是 service-worker.js。
chrome.runtime.sendMessage('sidePanelInit', showDef);
chrome.contextMenus.onClicked.addListener((info, tab) => {
if (info.menuItemId === 'define-word') {
showDef(info.selectionText);
}
});
function showDef(text) {
document.querySelector('#definition-word').textContent = text;
}