键盘快捷键

概览

该功能允许你为 Electron 应用程序配置应用和全局键盘快捷键。

示例

本地快捷键

应用键盘快捷键仅在应用程序被聚焦时触发。 为了配置本地快捷键,你需要在创建Menu模块中的MenuItem时指定accelerator属性。

Starting with a working application from the Quick Start Guide, update the main.js file with the following lines:

  • index.html
  • main.js
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Hello World!</title>
  6. <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
  7. </head>
  8. <body>
  9. <h1>Hello World!</h1>
  10. <p>Hit Alt+Shift+I on Windows, or Opt+Cmd+I on mac to see a message printed to the console.</p>
  11. </body>
  12. </html>
  1. const { app, BrowserWindow, Menu, MenuItem } = require('electron')
  2. function createWindow () {
  3. const win = new BrowserWindow({
  4. width: 800,
  5. height: 600,
  6. })
  7. win.loadFile('index.html')
  8. }
  9. const menu = new Menu()
  10. menu.append(new MenuItem({
  11. label: 'Electron',
  12. submenu: [{
  13. role: 'help',
  14. accelerator: process.platform === 'darwin' ? 'Alt+Cmd+I' : 'Alt+Shift+I',
  15. click: () => { console.log('Electron rocks!') }
  16. }]
  17. }))
  18. Menu.setApplicationMenu(menu)
  19. app.whenReady().then(createWindow)
  20. app.on('window-all-closed', () => {
  21. if (process.platform !== 'darwin') {
  22. app.quit()
  23. }
  24. })
  25. app.on('activate', () => {
  26. if (BrowserWindow.getAllWindows().length === 0) {
  27. createWindow()
  28. }
  29. })

Open in Fiddle

注意:在上面的代码中,您可以看到基于用户的操作系统的 accelerator 差异。 对于MacOS,是 Alt+Cmd+I,而对于Linux 和 Windows,则是 Alt+Shift+I.

启动 Electron 应用程序后,你应该看到应用程序菜单以及您刚刚定义的本地快捷方式:

带有本地快捷方式的菜单

如果你点击 Help 或按下定义的加速器,然后打开你运行的 Electron 应用程序的终端。 将看到触发 click 事件后生成的消息:“Electron rocks!”

全局快捷键

要配置全局键盘快捷键, 您需要使用 globalShortcon 模块来检测键盘事件,即使应用程序没有获得键盘焦点。

Starting with a working application from the Quick Start Guide, update the main.js file with the following lines:

  • index.html
  • main.js
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Hello World!</title>
  6. <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
  7. </head>
  8. <body>
  9. <h1>Hello World!</h1>
  10. <p>Hit Alt+Ctrl+I on Windows or Opt+Cmd+I on Mac to see a message printed to the console.</p>
  11. </body>
  12. </html>
  1. const { app, BrowserWindow, globalShortcut } = require('electron')
  2. function createWindow () {
  3. const win = new BrowserWindow({
  4. width: 800,
  5. height: 600,
  6. })
  7. win.loadFile('index.html')
  8. }
  9. app.whenReady().then(() => {
  10. globalShortcut.register('Alt+CommandOrControl+I', () => {
  11. console.log('Electron loves global shortcuts!')
  12. })
  13. }).then(createWindow)
  14. app.on('window-all-closed', () => {
  15. if (process.platform !== 'darwin') {
  16. app.quit()
  17. }
  18. })
  19. app.on('activate', () => {
  20. if (BrowserWindow.getAllWindows().length === 0) {
  21. createWindow()
  22. }
  23. })

Open in Fiddle

注:在上面的代码中, CommandOrControl 意指在 macOS 上使用 Command ,在 Windows/Linux 上使用 Control

启动应用后,如果你按下定义好的全局快捷键,你将在启动的 Electron 应用控制台里面看到对应的日志输出

在浏览器窗口内的快捷方式

使用 web APIs

如果您想要在 BrowserWindow 中处理键盘快捷键,你可以在渲染进程中使用 addEventListener() API来监听 kepupkeydown DOM事件

  • index.html
  • main.js
  • renderer.js
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
  6. <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
  7. <meta http-equiv="X-Content-Security-Policy" content="default-src 'self'; script-src 'self'">
  8. <title>Hello World!</title>
  9. </head>
  10. <body>
  11. <h1>Hello World!</h1>
  12. <p>Hit any key with this window focused to see it captured here.</p>
  13. <div><span>Last Key Pressed: </span><span id="last-keypress"></span></div>
  14. <script src="./renderer.js"></script>
  15. </body>
  16. </html>
  1. // Modules to control application life and create native browser window
  2. const {app, BrowserWindow} = require('electron')
  3. const path = require('path')
  4. function createWindow () {
  5. // Create the browser window.
  6. const mainWindow = new BrowserWindow({
  7. width: 800,
  8. height: 600,
  9. })
  10. // and load the index.html of the app.
  11. mainWindow.loadFile('index.html')
  12. }
  13. // This method will be called when Electron has finished
  14. // initialization and is ready to create browser windows.
  15. // Some APIs can only be used after this event occurs.
  16. app.whenReady().then(() => {
  17. createWindow()
  18. app.on('activate', function () {
  19. // On macOS it's common to re-create a window in the app when the
  20. // dock icon is clicked and there are no other windows open.
  21. if (BrowserWindow.getAllWindows().length === 0) createWindow()
  22. })
  23. })
  24. // Quit when all windows are closed, except on macOS. There, it's common
  25. // for applications and their menu bar to stay active until the user quits
  26. // explicitly with Cmd + Q.
  27. app.on('window-all-closed', function () {
  28. if (process.platform !== 'darwin') app.quit()
  29. })
  1. function handleKeyPress (event) {
  2. // You can put code here to handle the keypress.
  3. document.getElementById("last-keypress").innerText = event.key
  4. console.log(`You pressed ${event.key}`)
  5. }
  6. window.addEventListener('keyup', handleKeyPress, true)

Open in Fiddle

注意:第三个参数 true 表明了当前监听器会持续在其它监听器之前接收按键按下事件,因此无法在其它监听器中调用 stopPropagation()

拦截主进程中的事件

在调度页面中的keydownkeyup事件之前,会发出before-input-event事件。 它可以用于捕获和处理在菜单中不可见的自定义快捷方式。

Starting with a working application from the Quick Start Guide, update the main.js file with the following lines:

  • index.html
  • main.js
  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Hello World!</title>
  6. <meta http-equiv="Content-Security-Policy" content="script-src 'self' 'unsafe-inline';" />
  7. </head>
  8. <body>
  9. <h1>Hello World!</h1>
  10. <p>Hit Ctrl+I to see a message printed to the console.</p>
  11. </body>
  12. </html>
  1. const { app, BrowserWindow } = require('electron')
  2. app.whenReady().then(() => {
  3. const win = new BrowserWindow({ width: 800, height: 600 })
  4. win.loadFile('index.html')
  5. win.webContents.on('before-input-event', (event, input) => {
  6. if (input.control && input.key.toLowerCase() === 'i') {
  7. console.log('Pressed Control+I')
  8. event.preventDefault()
  9. }
  10. })
  11. })

Open in Fiddle

在运行Electron应用程序之后,如果你打开你运行Electron应用的终端并按下 Ctrl+I 组合键,你会发现刚才按下的组合键被成功拦截了。

使用第三方库

如果您不想手动进行快捷键解析,可以使用一些库来进行高级的按键检测。例如 mousetrap. 以下是在渲染进程中 mousetrap 的使用示例:

  1. Mousetrap.bind('4', () => { console.log('4') })
  2. Mousetrap.bind('?', () => { console.log('show shortcuts!') })
  3. Mousetrap.bind('esc', () => { console.log('escape') }, 'keyup')
  4. // combinations
  5. Mousetrap.bind('command+shift+k', () => { console.log('command shift k') })
  6. // map multiple combinations to the same callback
  7. Mousetrap.bind(['command+k', 'ctrl+k'], () => {
  8. console.log('command k or control k')
  9. // return false to prevent default behavior and stop event from bubbling
  10. return false
  11. })
  12. // gmail style sequences
  13. Mousetrap.bind('g i', () => { console.log('go to inbox') })
  14. Mousetrap.bind('* a', () => { console.log('select all') })
  15. // konami code!
  16. Mousetrap.bind('up up down down left right left right b a enter', () => {
  17. console.log('konami code')
  18. })