Skip to main content

上下文菜单

🌐 Context Menu

上下文菜单是当在应用界面某处右键点击(或使用快捷键,如在 Windows 上按 Shift+F10)时出现的弹出菜单。

在 Electron 中,默认情况下不会出现上下文菜单。然而,可以通过在 Menu 类的实例上使用 menu.popup 函数来创建上下文菜单。你需要监听特定的上下文菜单事件,并手动设置 menu.popup 的触发器。

🌐 No context menu will appear by default in Electron. However, context menus can be created by using the menu.popup function on an instance of the Menu class. You will need to listen for specific context menu events and set up the trigger for menu.popup manually.

在 Electron 中监听上下文菜单事件有两种方式:通过主进程的 webContents 或在渲染进程中通过 contextmenu Web 事件。

🌐 There are two ways of listening for context menu events in Electron: either via the main process through webContents or in the renderer process via the contextmenu web event.

使用 context-menu 事件(主)

🌐 Using the context-menu event (main)

每当在特定的 WebContents 实例范围内检测到右键点击时,会触发一个 context-menu 事件。传递给监听器的 params 对象提供了一个详细的属性列表,以区分正在接收事件的元素类型。

🌐 Whenever a right-click is detected within the bounds of a specific WebContents instance, a context-menu event is triggered. The params object passed to the listener provides an extensive list of attributes to distinguish which type of element is receiving the event.

例如,如果你想为链接提供上下文菜单,请检查 linkURL 参数。如果你想检查可编辑元素,如 <textarea/>,请检查 isEditable 参数。

🌐 For example, if you want to provide a context menu for links, check for the linkURL parameter. If you want to check for editable elements such as <textarea/>, check for the isEditable parameter.

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) => {
// only show the context menu if the element is editable
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 事件(渲染器)

🌐 Using the contextmenu event (renderer)

或者,你也可以监听在渲染进程的 DOM 元素上可用的 contextmenu 事件,并通过 IPC 调用 menu.popup 函数。

🌐 Alternatively, you can also listen to the contextmenu event available on DOM elements in the renderer process and call the menu.popup function via IPC.

tip

要了解有关 Electron 中 IPC 基础的更多信息,请参阅 进程间通信 指南。

const { ipcRenderer } = require('electron/renderer')

document.addEventListener('DOMContentLoaded', () => {
const textarea = document.getElementById('editable')
textarea.addEventListener('contextmenu', (event) => {
event.preventDefault()
ipcRenderer.send('context-menu')
})
})

额外的 macOS 菜单项(例如:写作工具)

🌐 Additional macOS menu items (e.g. Writing Tools)

在 macOS 上,Electron 中的 Writing ToolsAutoFillServices 菜单项默认在上下文菜单中被禁用。要启用这些功能,请将与目标 webContents 关联的 WebFrameMain 传递给 menu.popup 中的 frame 参数。

🌐 On macOS, the Writing Tools, AutoFill, and Services menu items are disabled by default for context menus in Electron. To enable these features, pass the WebFrameMain associated to the target webContents to the frame parameter in menu.popup.

Associating a frame to the context menu
const { BrowserWindow, Menu } = require('electron/main')

const menu = Menu.buildFromTemplate([{ role: 'editMenu' }])
const win = new BrowserWindow()
win.webContents.on('context-menu', (_event, params) => {
// Whether the context is editable.
if (params.isEditable) {
menu.popup({
frame: params.frame
})
}
})