基于chrome-extension-boilerplate-react-vite,如何实现右键菜单触发网页JSX模态框?
基于chrome-extension-boilerplate-react-vite实现上下文菜单触发JSX模态框的修改步骤
1. 更新background.ts,添加消息通知逻辑
修改背景脚本中上下文菜单的点击事件处理,当用户点击菜单时,向当前标签页的内容脚本发送显示模态框的消息:
import reloadOnUpdate from 'virtual:reload-on-update-in-background-script'; import 'webextension-polyfill'; reloadOnUpdate('pages/background'); reloadOnUpdate('pages/content/style.scss'); chrome.runtime.onInstalled.addListener(() => { console.log('onInstalled....'); chrome.contextMenus.create({ id: 'typelessPopup', title: 'Add to typless', contexts: ['selection'], }); }); chrome.contextMenus.onClicked.addListener((info, tab) => { if (tab?.id && info.menuItemId === 'typelessPopup') { // 存储选中文本(可选,也可通过消息直接传递) chrome.storage.local.set({ selectedText: info.selectionText }); // 向当前标签页发送消息触发模态框 chrome.tabs.sendMessage(tab.id, { type: 'SHOW_MODAL', payload: { selectedText: info.selectionText } }); } }); console.log('background loaded', chrome);
2. 修改内容脚本(pages/content/index.tsx),监听消息并渲染模态框
内容脚本负责在页面中注入React模态框,需要创建挂载容器并监听来自背景脚本的消息:
import React from 'react'; import ReactDOM from 'react-dom/client'; import './style.scss'; import Modal from '../../components/Modal'; // 创建模态框挂载容器 const createModalContainer = () => { const container = document.createElement('div'); container.id = 'typeless-modal-container'; document.body.appendChild(container); return container; }; const container = createModalContainer(); const root = ReactDOM.createRoot(container); // 初始状态不渲染模态框 root.render(null); // 监听背景脚本的消息 chrome.runtime.onMessage.addListener((message) => { if (message.type === 'SHOW_MODAL') { root.render( <Modal selectedText={message.payload.selectedText} onClose={() => root.render(null)} /> ); } });
3. 创建React模态框组件(components/Modal.tsx)
编写自定义模态框组件,展示选中的文本并提供交互功能:
import React from 'react'; interface ModalProps { selectedText: string; onClose: () => void; } const Modal = ({ selectedText, onClose }: ModalProps) => { return ( <div className="typeless-modal-overlay"> <div className="typeless-modal"> <button className="modal-close-btn" onClick={onClose}>×</button> <h3>选中的文本</h3> <p>{selectedText}</p> <button className="modal-submit-btn">添加到Typless</button> </div> </div> ); }; export default Modal;
4. 添加模态框样式(pages/content/style.scss)
为模态框编写基础样式,确保在页面顶部正确显示:
.typeless-modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.5); display: flex; justify-content: center; align-items: flex-start; padding-top: 50px; z-index: 999999; } .typeless-modal { background: #fff; padding: 24px; border-radius: 8px; width: 420px; box-shadow: 0 4px 16px rgba(0,0,0,0.2); position: relative; } .modal-close-btn { position: absolute; top: 12px; right: 16px; border: none; background: transparent; font-size: 20px; cursor: pointer; color: #666; } .modal-close-btn:hover { color: #000; } .modal-submit-btn { margin-top: 16px; padding: 10px 20px; background: #2563eb; color: #fff; border: none; border-radius: 4px; cursor: pointer; } .modal-submit-btn:hover { background: #1d4ed8; }
5. 检查Manifest配置(确保内容脚本注入范围正确)
确认项目中自动生成的Manifest配置里,content_scripts的matches字段包含你需要注入的网站,比如<all_urls>表示所有网站:
{ "content_scripts": [ { "matches": ["<all_urls>"], "js": ["pages/content/index.js"], "css": ["pages/content/style.css"] } ] }
内容的提问来源于stack exchange,提问作者Rooban
相关产品推荐
相关产品推荐

