菜单与快捷键

尽管咱们在平时应用桌面软件时,大多数状况下都是用鼠标进行操作,一些软件提供了菜单与键盘快捷键进行操作,mac零碎上比拟常见一些。如果在应用软件时有对应的快捷键操作或者菜单,会让用户的应用体验更加顺畅和不便一点。本章次要对注册快捷键的几种形式进行阐明以及菜单的零碎差异化解决。

Menu菜单

菜单这个货色呢,个别常见于mac零碎上,win的话国内比拟少见,算是一种约定俗成吧。实际上快捷键和菜单方面能够说是一体的,咱们能够在菜单上注册对应的键盘按键,故mac零碎能够应用这个形式把快捷键一起解决了。
长处:最简洁的快捷键解决,简略不便。
毛病:只能在应用程序被聚焦时触发(焦点在程序上,不只是显示),因为win个别不应用菜单,故只能用于mac上。

import { app, dialog, Menu } from 'electron'import config from './index'import global from './global'const os = require('os')const isMac = process.platform === 'darwin'const menuConfig = [{  label: app.name,  submenu: [{    label: '对于',    accelerator: isMac ? 'Alt+Cmd+I' : 'Alt+Shift+I',    click: function () {      info()    }  }]}, {  label: '设置',  submenu: [{    label: '疾速重启',    accelerator: 'CmdOrCtrl+F5',    role: 'reload'  }, {    label: '退出',    accelerator: 'CmdOrCtrl+Q',    role: 'quit'  }]}, {  label: '开发者设置',  submenu: [{    label: '切换到开发者模式',    accelerator: 'CmdOrCtrl+I',    role: 'toggledevtools'  }]}]function info() {  dialog.showMessageBox({    title: '对于',    type: 'info',    message: 'vue-cli-electron',    // detail: `版本信息:\nelectron版本:${process.versions.electron}\n以后零碎:${os.type()} ${os.arch()} ${os.release()}\n以后版本:${process.env.VUE_APP_ENV},${process.env.VUE_APP_VERSION}`,    detail: `版本信息:\nelectron版本:${process.versions.electron}\n以后零碎:${os.type()} ${os.arch()} ${os.release()}\n以后版本:${global.envConfig.VUE_APP_ENV},${global.envConfig.VUE_APP_VERSION}`,    noLink: true,    buttons: ['确定']  })}

菜单的快捷键注册是用accelerator增加的,当然你也能够依据零碎的不同进行差异化解决,role的话是electron内置的行为,比方copy - 复制paste - 粘贴等等,能够参考官网文档

在windows下咱们把菜单暗藏掉,mac的话失常显示:

function setMenu(win) {  let menu  if (config.devToolsShow) {    menu = Menu.buildFromTemplate(menuConfig)    Menu.setApplicationMenu(menu)    win.webContents.openDevTools({ mode: 'detach' })  } else {    if (isMac) {      menu = Menu.buildFromTemplate(menuConfig)      Menu.setApplicationMenu(menu)    } else {      Menu.setApplicationMenu(null)    }    win.webContents.openDevTools({ mode: 'detach' })    // win.webContents.closeDevTools()  }}

主过程监听快捷键

globalShortcut

globalShortcut模块能够在操作系统中注册/登记全局快捷键,然而集体不举荐用这种形式来注册快捷键:
长处:响应级别最高,只有软件在运行中,无论软件处于什么状态(没聚焦甚至暗藏),都会响应。
毛病:如果快捷键曾经被其余应用程序注册掉,那么会注册失败。注册胜利后,因为其响应级别最高,所以会影响其他软件快捷键的应用,在启动软件后,其他软件的快捷键雷同的话其他软件的快捷键无奈失效。

// 主过程,渲染过程能够应用remote来注册:const { app, globalShortcut } = require('electron')app.whenReady().then(() => {  const ret = globalShortcut.register('CommandOrControl+X', () => {    console.log('CommandOrControl+X is pressed')  })  if (!ret) {    console.log('registration failed')  }  // 查看快捷键是否注册胜利  console.log(globalShortcut.isRegistered('CommandOrControl+X'))})app.on('will-quit', () => {  // 登记快捷键  globalShortcut.unregister('CommandOrControl+X')  // 登记所有快捷键  globalShortcut.unregisterAll()})

electron-localshortcut

第三方的npm包,api和globalShortcut基本一致,相对而言没那么激进,是针对于窗口注册的,故需传入窗口进行注册,当窗口没聚焦时,不会相应。
长处:针对于窗口的监听,响应需处于聚焦状态,基本上能满足大多数场景。
毛病:须要引入第三方包,页面有webview,且焦点在webview上时无奈触发。

npm install --save electron-localshortcutconst electronLocalshortcut = require('electron-localshortcut')const win = new BrowserWindow()win.loadUrl('https://github.com')win.show()electronLocalshortcut.register(win, 'Ctrl+A', () => {  console.log('You pressed ctrl & A')})// 查看快捷键是否注册胜利console.log(electronLocalshortcut.isRegistered(win, 'Ctrl+A'))// 登记快捷键electronLocalshortcut.unregister(win, 'Ctrl+A')electronLocalshortcut.unregisterAll(win)

渲染过程监听快捷键

本人页面监听

实际上就是网页keyup的监听,能够用通信把键盘按键的信息传送到主过程。
当然你也能够在主过程中应用before-input-event,渲染过程中调度页面中的keydown和keyup事件之前,会收回before-input-event事件,能够在主过程捕捉按键信息。
长处:针对于页面的监听,罕用于某个页面的非凡按键监听。
毛病:页面有iframe或webview,且焦点在iframe或webview上时,无奈触发(iframe能够触发before-input-event)。

渲染过程:window.addEventListener('keyup', handleKeyPress, true)function handleKeyPress(event) {  $message.success(`keyup 监听${event.key}`)  console.log(`You pressed ${event.key}`)}window.removeEventListener('keyup', handleKeyPress, true)主过程:win.webContents.on('before-input-event', (event, input) => {  if (input.control && input.key.toLowerCase() === 'i') {    console.log('Pressed Control+I')    event.preventDefault()  }})

组合按键:当然一般来说快捷键都是组合按键的,咱们能够借助第三方按键库来解决。

npm i mousetrap渲染过程:Mousetrap.bind('ctrl+k', function() {   $message.success(`Mousetrap ctrl+k`)})Mousetrap.unbind('ctrl+k')

webview或iframe嵌入网页监听

如果咱们的页面中有webview或iframe,且焦点在webview或iframe上时,会导致咱们的快捷键生效。

  1. Menu菜单和globalShortcut不会生效。
  2. electron-localshortcut:webview有效,iframe无效
  3. keyup:webview有效,iframe有效,before-input-event:iframe无效。

这样看下来在利用webview的时候比拟难解决,只有Menu菜单和globalShortcut对其失效,那么还有其余形式吗?
咱们能够通过向webview注入preload.js来进行键盘按键的监听,而后将键盘信息回传给咱们的渲染过程

vue.config.js中electronBuilder批改为:preload: { preload: 'src/renderer/preload/ipcRenderer.js', webviewPreload: 'src/renderer/preload/webview.js' }webviewPreload是咱们向webview注入的js,当然你得新建对应文件,留神一下咱们建设的文件是webview.js,编译后为webviewPreload.js,故咱们注入的为webviewPreload.js。注:webview 启动及Node integration启用须在主过程窗口webPreferences进行配置。webview.js:const { ipcRenderer } = require('electron')window.addEventListener('keyup', handleKeyPress, true)function handleKeyPress(event) {    console.log(event.key)    ipcRenderer.sendToHost('ipc-message', {        data: event.key    })}渲染过程:<webview ref="webviewRef" class="webview" src="https://www.baidu.com" :preload="state.preload" ></webview>const { remote } = require('electron')const path = require('path')const webview = webviewRef.valuestate.preload = path.resolve(remote.app.getAppPath(), './webviewPreload.js')webview.addEventListener('ipc-message', webMessage)webview.addEventListener('dom-ready', () => {  webview.openDevTools()})function webMessage(event) {  console.log('在此监听事件中接管webview嵌套页面所响应的事件', event)  $message.success(`webview:${event.args[0].data}`)}

简略梳理一下,咱们把webviewPreload.js注入webview,通过这个js进行键盘的keyup监听,而后通过sendToHost把信息回传给渲染过程,渲染过程中获取回传的信息。
渲染过程是看不到咱们注入js以及webview的打印,能够应用webview.openDevTools(),关上webview的控制台查看。
本例子就没阐明组合键了,想用组合键请自行注入mousetrap进行操作。

本系列更新只有利用周末和下班时间整顿,比拟多的内容的话更新会比较慢,心愿能对你有所帮忙,请多多star或点赞珍藏反对一下

本文地址:链接
本文github地址:链接