在 Electron 中默认右键是不会弹出菜单的,就连 inputtextarea 这一类输入框也不会弹出菜单。右键菜单可以使用 HTML 制作,也可以使用原生菜单,原生菜单的键盘可访问性要好一些。

创建菜单

Electron 的上下文菜单需要在渲染进程中创建,下面是一个简单的菜单:

const { remote } = require('electron');  // 引入 remote

// 菜单模板
const menuTemplate = [
  { label: '全选' },
  { label: '复制' },
  { label: '粘贴' }
];

// 构建菜单项
const menu = remote.Menu.buildFromTemplate(menuTemplate);

// 菜单键点击
window.addEventListener('contextmenu', ev => {
  // 阻止默认行为
  ev.preventDefault();
  // 弹出上下文菜单
  menu.popup({
    // 获取网页所属的窗口
    window: remote.getCurrentWindow()
  });
});

上面给 window 添加了菜单事件,只要右击窗口的页面区域就能弹出菜单,菜单位置就是鼠标位置。

点击事件还是和 菜单栏 一样的在菜单模板的菜单项编写 click 函数,如下:

// 菜单模板
const menuTemplate = [
  {
    label: '红色',
    click() {
      document.body.style.background = 'red';
    }
  },
  {
    label: '绿色',
    click() {
      document.body.style.background = 'green';
    }
  },
  {
    label: '蓝色',
    click() {
      document.body.style.background = 'blue';
    }
  }
];

Electron 官方已经准备弃用 remote 模块,如果控制台报错找不到 remoteMenu 可以尝试在 main 主进程创建 BrowserWindow 的选项的 webPreferences 中把 enableRemoteModule 设置为 true ,如下:

new BrowserWindow({
  width: 600,
  height: 600,
  webPreferences: {
    nodeIntegration: true,
    contextIsolation: false,
    enableRemoteModule: true
  }
});

enableRemoteModule 设置为 true

主进程上下文菜单

如果 Electron 官方彻底弃用了 remote 也可以考虑把上下文菜单放到主进程,使用 ipcRendereripcMain 调用菜单,Electron 官方文档也是推荐使用 ipcRendereripcMain

下面给 textarea 添加右键上下文菜单,

渲染进程:

// 引入 ipcRenderer 模块
const {ipcRenderer} = require('electron');
// 获取 textarea
const textarea = document.querySelector('textarea');

// textarea 菜单键点击
textarea.addEventListener('contextmenu', ev => {
  // 阻止默认行为
  ev.preventDefault();
  // 获取鼠标位置
  const client = {
    x: ev.clientX,
    y: ev.clientY
  };
  // 把鼠标位置发送到主进程
  ipcRenderer.send('menu', client);
});

主进程:

// 引入 Menu 和 ipcMain 模块
const {Menu, ipcMain} = require('electron');

// 菜单模板
const menuTemplate = [
  {
    label: '全选',
    role: 'selectAll'
  },
  {
    label: '剪贴',
    role: 'cut'
  },
  {
    label: '复制',
    role: 'copy'
  },
  {
    label: '粘贴',
    role: 'paste'
  }
];

// 构建菜单项
const menu = Menu.buildFromTemplate(menuTemplate);
// 监听菜单请求
ipcMain.on('menu', (ev, arg) => {
  // 弹出上下文菜单
  menu.popup({
    x: arg.x,
    y: arg.y
  });
});

这里的 role 属性是预定义功能,可以直接使用 role 实现的就不需要手动编写 click

完整的 role 属性可以访问 https://www.electronjs.org/docs/api/menu-item 查看。

上面给 textarea 添加了右键的上下文菜单,效果如下:

Electron上下文菜单

以上就是右键上下文菜单的基本配置,其他 checkbox 多选和 radio 单选菜单可以参考 菜单栏 的配置,动态添加菜单项也可以参考 菜单栏 的配置。

相关文章: