如何使用JavaScript编辑选中文本时的右键上下文菜单
如何使用JavaScript编辑选中文本时的右键上下文菜单
嗨,我懂你想实现类似Postman那样,在选中文本的右键菜单里添加自定义选项,同时保留原有菜单功能的需求。这里得分两种场景来实现,我给你详细讲讲:
一、浏览器扩展场景(和Postman实现方式一致)
Postman这类浏览器扩展之所以能直接给原生右键菜单加选项,是用了浏览器提供的contextMenus API(Chrome、Edge等Chromium内核浏览器都支持)。步骤如下:
在扩展的manifest文件中声明权限
首先需要在manifest.json里添加contextMenus权限,同时指定matches来限定触发的网页范围:{ "manifest_version": 3, "name": "我的自定义右键菜单扩展", "version": "1.0", "permissions": ["contextMenus"], "content_scripts": [ { "matches": ["<all_urls>"], "js": ["content.js"] } ], "background": { "service_worker": "background.js" } }在后台脚本中创建右键菜单项
在background.js里注册右键菜单,指定只在选中文本时显示:chrome.runtime.onInstalled.addListener(() => { chrome.contextMenus.create({ id: "custom-text-action", title: "我的自定义文本操作", contexts: ["selection"] // 只在选中文本时显示 }); }); // 监听菜单项点击事件 chrome.contextMenus.onClicked.addListener((info, tab) => { if (info.menuItemId === "custom-text-action") { // info.selectionText就是用户选中的文本 console.log("选中的文本:", info.selectionText); // 这里可以写你的业务逻辑,比如发送到你的服务,或者处理文本 } });这样配置后,用户选中文本右键时,原生菜单里就会多出你添加的选项,完全和Postman的实现逻辑一样。
二、普通网页场景(模拟自定义菜单)
如果是在普通网页里,因为浏览器安全限制,我们无法直接修改原生右键菜单,只能自己模拟一个上下文菜单。你可以选择替换原生菜单为自定义的(包含原生常用选项+自定义选项),体验会更流畅。
下面是一个完整的模拟示例:
<!DOCTYPE html> <html> <body> <p>选中这段文本右键试试</p> <script> // 监听右键菜单事件 document.addEventListener('contextmenu', function(e) { const selectedText = window.getSelection().toString().trim(); if (selectedText) { e.preventDefault(); // 阻止原生菜单弹出 showCustomMenu(e.pageX, e.pageY, selectedText); } }); // 点击页面其他地方关闭自定义菜单 document.addEventListener('click', function() { const menu = document.getElementById('custom-context-menu'); if (menu) menu.remove(); }); function showCustomMenu(x, y, selectedText) { // 移除已存在的菜单 const existingMenu = document.getElementById('custom-context-menu'); if (existingMenu) existingMenu.remove(); // 创建菜单容器 const menu = document.createElement('div'); menu.id = 'custom-context-menu'; menu.style.cssText = ` position: absolute; left: ${x}px; top: ${y}px; background: #fff; border: 1px solid #e0e0e0; border-radius: 6px; box-shadow: 0 2px 15px rgba(0,0,0,0.1); z-index: 99999; min-width: 200px; font-family: Arial, sans-serif; font-size: 14px; `; // 原生常用选项:复制 const copyItem = createMenuItem('复制', () => { document.execCommand('copy'); menu.remove(); }); menu.appendChild(copyItem); // 添加分隔线 menu.appendChild(createSeparator()); // 自定义选项 const customItem = createMenuItem('我的自定义操作', () => { alert(`你选中的文本是:${selectedText}`); menu.remove(); }); menu.appendChild(customItem); document.body.appendChild(menu); } // 辅助函数:创建菜单项 function createMenuItem(text, onClick) { const item = document.createElement('div'); item.textContent = text; item.style.cssText = ` padding: 8px 16px; cursor: pointer; user-select: none; `; item.addEventListener('mouseover', () => { item.style.background = '#f5f5f5'; }); item.addEventListener('mouseout', () => { item.style.background = 'transparent'; }); item.addEventListener('click', onClick); return item; } // 辅助函数:创建分隔线 function createSeparator() { const separator = document.createElement('div'); separator.style.cssText = ` height: 1px; background: #e0e0e0; margin: 4px 0; `; return separator; } </script> </body> </html>
这个示例会在选中文本时弹出自定义菜单,包含“复制”(模拟原生功能)和你的自定义选项,点击页面其他地方会自动关闭菜单。
备注:内容来源于stack exchange,提问作者Rhyme Ahmed
相关产品推荐
相关产品推荐

