本文中,苏南大叔将要描述的是electron如何创建上下文菜单,上下文菜单其实就是平时大家常说的右键菜单。但是,需要明确的是:这个上下文菜单其实鼠标左键也可以触发的。或者说:上下文菜单的触发,并不局限于右键。

苏南大叔:electron程序,如何创建自定义上下文菜单? - electron-context-menu
electron程序,如何创建自定义上下文菜单?(图5-1)

本文测试环境:mac/electron@5.0.2。基础龙套项目源码是electron-quick-start。上下文菜单的样式,是系统默认样式,并不能做深度定制。如果您有及其丰富的想法创意,建议您不要使用本文中所涉及的context-menu,而是选择用纯网页的技术,模拟一个菜单出来。

构建菜单

context menu是在主进程中创建的,而传统的网页模拟菜单技术,是在渲染进程里面创建的。官方demo的创建方式如下:

const {Menu,MenuItem} = require('electron')
const menu = new Menu()
menu.append(new MenuItem({ label: 'Electron', type: 'checkbox', checked: true ,click:function(){console.log('click')}}))
menu.append(new MenuItem({ type: 'separator' }))
menu.append(new MenuItem({ label: 'selectall',role:"selectall" }))
menu.append(new MenuItem({ label: 'copy',role:"copy" }))
请注意:使用buildFromTemplate()方式,也可以构建上下文菜单的,这并不冲突。

苏南大叔:electron程序,如何创建自定义上下文菜单? - main-menu-init
electron程序,如何创建自定义上下文菜单?(图5-2)

触发菜单

全局无条件触发

页面任何位置点击右键即可触发context-menu

// const {app} = require('electron')
app.on('browser-window-created', (event, win) => {
   win.webContents.on('context-menu', (e, params) => {
     menu.popup(win, params.x, params.y)
   })
})

局部有条件的触发

需要触发上下文菜单的时候,只需要对主进程触发个ipc消息即可。至于触发的时机,是你自己说了算的。并不局限于鼠标右键触发。鼠标左键,或者某个键盘事件都是可以的。随你想象。

主进程:

ipcMain.on('show-context-menu', (event) => {
  const win = BrowserWindow.fromWebContents(event.sender)
  menu.popup(win)
})

渲染进程:

const {ipcRenderer} = require('electron')
const contextMenuBtn = document.getElementById('context-menu')
  contextMenuBtn.addEventListener('click', () => {
    ipcRenderer.send('show-context-menu')
})

局部触发不同的菜单

这个上下文菜单context-menu,实际上可以定义多个菜单对象,然后根据不同的情况(渲染进程dom),触发不同的菜单。比如:点击按钮的时候,是第一个菜单。点击图片的时候,显示第二个菜单。

  • 主进程上,主要任务就是建立不同的菜单,然后定义不同的ipcmain.on
  • 渲染进程上,主要的任务就是,对不同的dom绑定不同的ipcRenderer.send
  • 主进程和渲染进程的菜单,用ipc的名字(下例中是:show-context-menu2)进行联系。

苏南大叔:electron程序,如何创建自定义上下文菜单? - main-more-code
electron程序,如何创建自定义上下文菜单?(图5-3)

主进程:

ipcMain.on('show-context-menu2', (event) => {
  const win = BrowserWindow.fromWebContents(event.sender)
  menu2.popup(win)
})

渲染进程:

contextMenuBtn2.addEventListener('contextmenu', () => {
    ipcRenderer.send('show-context-menu2')
})

区分鼠标右键左键

const contextMenuBtn = document.getElementById('context-menu')
contextMenuBtn.addEventListener('click', (e) => {
  alert("left");
})
contextMenuBtn.addEventListener('contextmenu', (e) => {
  alert("right");
})
  • 监控click事件,是鼠标左键。
  • 监控contextmenu事件,是鼠标右键。

苏南大叔:electron程序,如何创建自定义上下文菜单? - renderer-code
electron程序,如何创建自定义上下文菜单?(图5-4)

对比总结

这个上下文菜单context menu和顶部菜单application menu是非常类似的。官方的例子中:

  • application menu是通过buildFromTemplate()添加的。
  • context menu是通过menu.append(new MenuItem())添加的。

但是,事实上,这两种菜单添加方式其实是通用的。

苏南大叔:electron程序,如何创建自定义上下文菜单? - context-menu
electron程序,如何创建自定义上下文菜单?(图5-5)

这两种菜单实际上有些差别的:

  • application menu的菜单,大多都是有二级菜单的,大多是有快捷键的。
  • context menu的菜单,大多都是没有二级菜单的,大多数情况下,是没用快捷键的。

相关链接

electron创建系统顶部菜单的方法如下:

本文中,苏南大叔就再不案例更多参数了。支持的参数可以参见下面的链接:

结束语

更多electron相关经验文字,请点击苏南大叔的博客,并且强烈建议您加入浏览器收藏夹。地址如下:

如果本文对您有帮助,或者节约了您的时间,欢迎打赏瓶饮料,建立下友谊关系。
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。
本站采用创作共用版权协议, 要求署名、非商业用途和相同方式共享。
转载本站内容必须也遵循“署名-非商业用途-相同方式共享”的创作共用协议。
未经许可,规模化镜像抄袭本站内容的行为,将会根据有关法律法规进行维权。
程序如此灵动~》下所有原创文章,如被用于商业用途,请您按规定支付稿费。

 【加群】加入QQ群【175454274】和大家一起讨论这个问题

 【源码】本文代码片段及相关软件,请点此获取

 【绝密】秘籍文章入口,仅传授于有缘之人   electron

本站的忠实读者小伙伴,正在阅读下面这些文章: