进阶 electronjs.org 2026-10-07 23:51:43 · 6 阅读
第10章 Electron 教程(第10章):Context Menu 上下文菜单
上下文菜单
上下文菜单是右键点击(或在 Windows 上按 Shift + F10 之类的快捷键)应用界面某处时弹出的菜单。
Electron 默认没有上下文菜单,但可以通过 Menu 类实例的 menu.popup 方法来创建。你需要手动监听相应的上下文菜单事件,并设置触发 menu.popup 的条件。
在 Electron 中监听上下文菜单事件有两种方式:一种是在主进程中通过 webContents 监听,另一种是在渲染进程中通过 web 的 contextmenu 事件监听。
使用 context-menu 事件(主进程)
在某个 WebContents 实例的范围内检测到右键点击时,就会触发 context-menu 事件。传给监听器的 params 对象提供了大量属性,可用于判断接收事件的元素类型。
比如,如果想为链接提供上下文菜单,就检查 linkURL 参数;如果想检测 这类可编辑元素,就检查 isEditable 参数。
docs/fiddles/menus/context-menu/web-contents (44.6.0) 在 Fiddle 中打开 main.js index.html const { app, BrowserWindow, Menu } = require('electron/main')
function createWindow () {
const win = new BrowserWindow()
const menu = Menu.buildFromTemplate([
{ role: 'copy' },
{ role: 'cut' },
{ role: 'paste' },
{ role: 'selectall' }
])
win.webContents.on('context-menu', (_event, params) => {
// 只在元素可编辑时显示上下文菜单
if (params.isEditable) {
menu.popup()
}
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
Context Menu Demo
在渲染进程中监听 contextmenu 事件 你也可以在渲染进程的 DOM 元素上监听 contextmenu 事件,然后通过 IPC 调用 menu.popup 方法。 提示 若需了解 Electron 中 IPC 的基础知识,请参阅进程间通信指南。 docs/fiddles/menus/context-menu/dom (44.6.0)Open in Fiddlemain.jspreload.jsindex.html // 用于控制应用生命周期和创建原生浏览器窗口的模块 const { app, BrowserWindow, ipcMain, Menu } = require('electron/main') const path = require('node:path') function createWindow () { const mainWindow = new BrowserWindow({ webPreferences: { preload: path.join(__dirname, 'preload.js') } }) mainWindow.loadFile('index.html') const menu = Menu.buildFromTemplate([ { role: 'copy' }, { role: 'cut' }, { role: 'paste' }, { role: 'selectall' } ]) ipcMain.on('context-menu', (event) => { menu.popup({ window: BrowserWindow.fromWebContents(event.sender) }) }) } app.whenReady().then(() => { createWindow() app.on('activate', function () { if (BrowserWindow.getAllWindows().length === 0) createWindow() }) }) app.on('window-all-closed', function () { if (process.platform !== 'darwin') app.quit() }) const { ipcRenderer } = require('electron/renderer') document.addEventListener('DOMContentLoaded', () => { const textarea = document.getElementById('editable') textarea.addEventListener('contextmenu', (event) => { event.preventDefault() ipcRenderer.send('context-menu') }) })右键菜单演示
function createWindow () {
const win = new BrowserWindow()
const menu = Menu.buildFromTemplate([
{ role: 'copy' },
{ role: 'cut' },
{ role: 'paste' },
{ role: 'selectall' }
])
win.webContents.on('context-menu', (_event, params) => {
// 只在元素可编辑时显示上下文菜单
if (params.isEditable) {
menu.popup()
}
})
win.loadFile('index.html')
}
app.whenReady().then(() => {
createWindow()
app.on('activate', function () {
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
})
在渲染进程中监听 contextmenu 事件 你也可以在渲染进程的 DOM 元素上监听 contextmenu 事件,然后通过 IPC 调用 menu.popup 方法。 提示 若需了解 Electron 中 IPC 的基础知识,请参阅进程间通信指南。 docs/fiddles/menus/context-menu/dom (44.6.0)Open in Fiddlemain.jspreload.jsindex.html // 用于控制应用生命周期和创建原生浏览器窗口的模块 const { app, BrowserWindow, ipcMain, Menu } = require('electron/main') const path = require('node:path') function createWindow () { const mainWindow = new BrowserWindow({ webPreferences: { preload: path.join(__dirname, 'preload.js') } }) mainWindow.loadFile('index.html') const menu = Menu.buildFromTemplate([ { role: 'copy' }, { role: 'cut' }, { role: 'paste' }, { role: 'selectall' } ]) ipcMain.on('context-menu', (event) => { menu.popup({ window: BrowserWindow.fromWebContents(event.sender) }) }) } app.whenReady().then(() => { createWindow() app.on('activate', function () { if (BrowserWindow.getAllWindows().length === 0) createWindow() }) }) app.on('window-all-closed', function () { if (process.platform !== 'darwin') app.quit() }) const { ipcRenderer } = require('electron/renderer') document.addEventListener('DOMContentLoaded', () => { const textarea = document.getElementById('editable') textarea.addEventListener('contextmenu', (event) => { event.preventDefault() ipcRenderer.send('context-menu') }) })