我希望侧面板能够显示并一键修改,但 Chrome 扩展程序需要点击两次?

问题描述 投票:0回答:1

我正在创建一个 Chrome 字典游戏扩展,该项目的第一部分要求用户能够右键单击一个单词,并且会出现一个侧面板,其中包含该单词的定义(使用本地数据库找到的定义)。 但是,我遇到了一个小问题。用户必须右键单击该单词,然后按“定义”两次,一次拉起侧面板,然后第二次显示定义。 第一次点击时,它会显示: [1]:https://i.stack.imgur.com/wVHsD.png 第二次点击“WordBank It!”然后它会在侧面板上显示定义: [2]:https://i.stack.imgur.com/t8CFv.png 我希望它打开侧面板一键显示定义,显然是为了更好的易用性。我怎样才能这样做呢?这是我的代码文件:

// 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"]
}

我该怎么办?

javascript reactjs google-chrome-extension
1个回答
0
投票

您需要将 service-worker.js 拆分为两个脚本,因为您有两个不同的上下文。 Service Worker 将注册菜单并处理菜单命令,然后打开侧面板并通过消息传递将所选文本发送到其脚本。当侧面板打开时,将直接收听菜单。

service-worker.js:

删除

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.html:

加载 sidepanel.js 而不是 service-worker.js。

sidepanel.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;
}
© www.soinside.com 2019 - 2024. All rights reserved.