hotkeys-js vs keymaster vs mousetrap
JavaScript Keyboard Shortcut Libraries
hotkeys-jskeymastermousetrap

JavaScript Keyboard Shortcut Libraries

JavaScript keyboard shortcut libraries are designed to simplify the process of capturing and handling keyboard events in web applications. They provide a straightforward API for defining keyboard shortcuts, allowing developers to enhance user experience by enabling quick access to functionalities through key combinations. These libraries help in managing complex key bindings and ensure that keyboard interactions are intuitive and responsive, contributing to a more efficient workflow for users.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
hotkeys-js07,1244.57 MB15916 days agoMIT
keymaster06,520-8212 years ago-
mousetrap011,792-2376 years agoApache-2.0 WITH LLVM-exception

Feature Comparison: hotkeys-js vs keymaster vs mousetrap

Ease of Use

  • hotkeys-js:

    hotkeys-js offers a straightforward API that allows developers to define keyboard shortcuts with minimal code. Its intuitive syntax makes it easy to implement and manage complex key combinations, making it accessible for developers of all skill levels.

  • keymaster:

    keymaster is designed for simplicity, providing a clean and minimalistic API that allows for quick setup of keyboard shortcuts. Developers can easily bind keys to functions without the need for extensive configuration, making it ideal for small projects or prototypes.

  • mousetrap:

    mousetrap provides a user-friendly interface for defining keyboard shortcuts. It allows for easy binding of keys to functions and supports various key combinations, making it simple for developers to implement keyboard interactions in their applications.

Feature Set

  • hotkeys-js:

    hotkeys-js supports advanced features such as nested shortcuts, key sequence detection, and the ability to disable shortcuts dynamically. This makes it a powerful choice for applications that require intricate keyboard interactions and user customization.

  • keymaster:

    keymaster focuses on the core functionality of key binding without additional features. It provides essential capabilities for defining shortcuts but lacks advanced functionalities like sequence detection or dynamic disabling, making it suitable for simpler applications.

  • mousetrap:

    mousetrap offers a rich feature set, including support for global shortcuts, key sequences, and event handling across different browsers. It is well-equipped to handle complex keyboard interactions, making it a versatile choice for applications that require extensive keyboard support.

Browser Compatibility

  • hotkeys-js:

    hotkeys-js is designed to work seamlessly across modern browsers, ensuring consistent behavior for keyboard shortcuts. It handles browser-specific quirks, providing a reliable experience for users regardless of their browser choice.

  • keymaster:

    keymaster is lightweight and focuses on compatibility with modern browsers. However, it may not fully support older browsers, so it's best suited for applications targeting contemporary web environments.

  • mousetrap:

    mousetrap is known for its excellent cross-browser compatibility, ensuring that keyboard shortcuts function correctly across different platforms. It addresses common issues related to key events in various browsers, making it a robust choice for applications with diverse user bases.

Community and Support

  • hotkeys-js:

    hotkeys-js has a growing community and is actively maintained, providing developers with resources and support. Its documentation is clear and comprehensive, making it easier for new users to get started and find solutions to common issues.

  • keymaster:

    keymaster has a smaller community compared to other libraries, which may result in limited support and resources. However, its simplicity means that many developers can quickly understand and implement it without extensive documentation.

  • mousetrap:

    mousetrap boasts a solid community and extensive documentation, offering ample resources for developers. Its popularity ensures that users can find help and examples easily, making it a reliable choice for projects requiring community support.

Performance

  • hotkeys-js:

    hotkeys-js is optimized for performance, allowing for quick execution of keyboard shortcuts without significant overhead. Its lightweight nature ensures that it does not slow down the application, even with numerous key bindings.

  • keymaster:

    keymaster is designed to be minimalistic, which contributes to its performance. It efficiently handles key events without unnecessary complexity, making it suitable for applications where performance is a critical concern.

  • mousetrap:

    mousetrap is built for performance, efficiently managing keyboard events and ensuring that shortcuts are processed quickly. Its design allows for rapid execution of key bindings, making it a strong choice for applications with high keyboard interaction.

How to Choose: hotkeys-js vs keymaster vs mousetrap

  • hotkeys-js:

    Choose hotkeys-js if you need a lightweight library that supports complex key combinations and offers a simple syntax for defining shortcuts. It is particularly useful for applications that require a high level of customization and flexibility in key bindings.

  • keymaster:

    Opt for keymaster if you are looking for a minimalistic approach to keyboard shortcuts with a focus on simplicity and ease of use. It is ideal for projects where you want to quickly set up basic key bindings without much overhead.

  • mousetrap:

    Select mousetrap if you need a robust solution that supports global shortcuts and has built-in support for key combinations across different browsers. It is well-suited for applications that require extensive keyboard interaction and need to handle various key events effectively.

README for hotkeys-js

Using my app is also a way to support me:
Scap: Screenshot & Markup Edit Screen Test Deskmark Keyzer Vidwall Hub VidCrop Vidwall Mousio Hint Mousio Musicer Audioer FileSentinel FocusCursor Videoer KeyClicker DayBar Iconed Menuist Quick RSS Quick RSS Web Serve Copybook Generator DevTutor for SwiftUI RegexMate Time Passage Iconize Folder Textsound Saver Create Custom Symbols DevHub Resume Revise Palette Genius Symbol Scribe

Hotkeys

Buy me a coffee Follow On X GitHub Actions CI Coverage Status Chinese jaywcjlove/hotkeys-js

HotKeys.js is an input capture library with some very special features, it is easy to pick up and use, has a reasonable footprint (~8kB) (gzipped: 3.8kB), and has no dependencies. It should not interfere with any JavaScript libraries or frameworks. Official document demo preview, compatibility test. More examples.

╭┈┈╮          ╭┈┈╮  ╭┈┈╮
┆  ├┈┈..┈┈┈┈┈.┆  └┈╮┆  ├┈┈..┈┈┈┈┈..┈┈.┈┈..┈┈┈┈┈.
┆     ┆┆  □  ┆┆   ┈┤┆    < ┆  -__┘┆  ┆  ┆┆__ ┈┈┤
╰┈┈┴┈┈╯╰┈┈┈┈┈╯╰┈┈┈┈╯╰┈┈┴┈┈╯╰┈┈┈┈┈╯╰┈┈┈  ┆╰┈┈┈┈┈╯
                                  ╰┈┈┈┈┈╯

Usage

You will need Node.js installed on your system.

npm install hotkeys-js --save
import hotkeys from 'hotkeys-js';

hotkeys('f5', function(event, handler){
  // Prevent the default refresh event under WINDOWS system
  event.preventDefault()
  alert('you pressed F5!')
});

Browser Usage

Or manually download and link hotkeys.js in your HTML. The library provides different formats for different use cases:

CDN Links: UNPKG | jsDelivr | Githack | Statically

Available Formats:

IIFE (Immediately Invoked Function Expression) - Recommended for direct browser usage:

<script src="https://unpkg.com/hotkeys-js/dist/hotkeys-js.min.js">
</script>
<script type="text/javascript">
hotkeys('ctrl+a,ctrl+b,r,f', function (event, handler){
  switch (handler.key) {
    case 'ctrl+a': alert('you pressed ctrl+a!');
      break;
    case 'ctrl+b': alert('you pressed ctrl+b!');
      break;
    case 'r': alert('you pressed r!');
      break;
    case 'f': alert('you pressed f!');
      break;
    default: alert(event);
  }
});
</script>

UMD (Universal Module Definition) - For CommonJS/AMD environments:

<script src="https://unpkg.com/hotkeys-js/dist/hotkeys-js.umd.cjs">
</script>

ES Module - For modern browsers with module support:

<script type="module">
import hotkeys from 'https://unpkg.com/hotkeys-js/dist/hotkeys-js.js';
hotkeys('ctrl+a', function(event, handler){
  alert('you pressed ctrl+a!');
});
</script>

Used in React

react-hotkeys is the React component that listen to keydown and keyup keyboard events, defining and dispatching keyboard shortcuts. Detailed use method please see its documentation react-hotkeys.

react-hotkeys-hook - React hook for using keyboard shortcuts in components. Make sure that you have at least version 16.8 of react and react-dom installed, or otherwise hooks won't work for you.

Browser Support

Hotkeys.js has been tested and should work in.

Internet Explorer 6+
Safari
Firefox
Chrome

Supported Keys

HotKeys understands the following modifiers: , shift, option, , alt, ctrl, control, command, and .

The following special keys can be used for shortcuts: backspace, tab, clear, enter, return, esc, escape, space, up, down, left, right, home, end, pageup, pagedown, del, delete, f1 through f19, num_0 through num_9, num_multiply, num_add, num_enter, num_subtract, num_decimal, num_divide.

Command()
Control
Option(alt)
Shift
Caps Lock(Capital)
fn Does not support fn
↩︎ return/Enter space

Defining Shortcuts

One global method is exposed, key which defines shortcuts when called directly.

declare interface HotkeysInterface extends HotkeysAPI {
  (key: string, method: KeyHandler): void;
  (key: string, scope: string, method: KeyHandler): void;
  (key: string, option: HotkeysOptions, method: KeyHandler): void;
  shift?: boolean;
  ctrl?: boolean;
  alt?: boolean;
  option?: boolean;
  control?: boolean;
  cmd?: boolean;
  command?: boolean;
}
declare interface HotkeysAPI {
  setScope: SetScope;
  getScope: GetScope;
  deleteScope: DeleteScope;
  getPressedKeyCodes: GetPressedKeyCodes;
  getPressedKeyString: GetPressedKeyString;
  getAllKeyCodes: GetAllKeyCodes;
  isPressed: IsPressed;
  filter: Filter;
  trigger: Trigger;
  unbind: Unbind;
  noConflict: NoConflict;
  keyMap: Record<string, number>;
  modifier: Record<string, number>;
  modifierMap: Record<string | number, number | string>;
}
hotkeys('f5', function(event, handler) {
  // Prevent the default refresh event under WINDOWS system
  event.preventDefault();
  alert('you pressed F5!');
});

// Returning false stops the event and prevents default browser events
// Mac OS system defines `command + r` as a refresh shortcut
hotkeys('ctrl+r, command+r', function() {
  alert('stopped reload!');
  return false;
});

// Single key
hotkeys('a', function(event,handler){
  //event.srcElement: input
  //event.target: input
  if(event.target === "input"){
      alert('you pressed a!')
  }
  alert('you pressed a!')
});

// Key Combination
hotkeys('ctrl+a,ctrl+b,r,f', function (event, handler){
  switch (handler.key) {
    case 'ctrl+a': alert('you pressed ctrl+a!');
      break;
    case 'ctrl+b': alert('you pressed ctrl+b!');
      break;
    case 'r': alert('you pressed r!');
      break;
    case 'f': alert('you pressed f!');
      break;
    default: alert(event);
  }
});

hotkeys('ctrl+a+s', function() {
    alert('you pressed ctrl+a+s!');
});

// Using a scope
hotkeys('*','wcj', function(event){
  console.log('do something', event);
});

option

  • scope<String>: Sets the scope in which the shortcut key is active
  • element<HTMLElement>: Specifies the DOM element to bind the event to
  • keyup<Boolean>: Whether to trigger the shortcut on key release
  • keydown<Boolean>: Whether to trigger the shortcut on key press
  • splitKey<String>: Delimiter for key combinations (default is +)
  • capture<Boolean>: Whether to trigger the listener during the capture phase (before the event bubbles down)
  • single<Boolean>: Allows only one callback function (automatically unbinds previous one)
hotkeys('o, enter', {
  scope: 'wcj',
  element: document.getElementById('wrapper'),
}, function() {
  console.log('do something else');
});

hotkeys('ctrl-+', { splitKey: '-' }, function(e) {
  console.log('you pressed ctrl and +');
});

hotkeys('+', { splitKey: '-' }, function(e){
  console.log('you pressed +');
})

keyup

key down and key up both perform callback events.

hotkeys('ctrl+a,alt+a+s', {keyup: true}, function(event, handler) {
  if (event.type === 'keydown') {
    console.log('keydown:', event.type, handler, handler.key);
  }

  if (event.type === 'keyup') {
    console.log('keyup:', event.type, handler, handler.key);
  }
});

API REFERENCE

Asterisk "*"

Modifier key judgments

hotkeys('*', function() {
  if (hotkeys.shift) {
    console.log('shift is pressed!');
  }

  if (hotkeys.ctrl) {
    console.log('ctrl is pressed!');
  }

  if (hotkeys.alt) {
    console.log('alt is pressed!');
  }

  if (hotkeys.option) {
    console.log('option is pressed!');
  }

  if (hotkeys.control) {
    console.log('control is pressed!');
  }

  if (hotkeys.cmd) {
    console.log('cmd is pressed!');
  }

  if (hotkeys.command) {
    console.log('command is pressed!');
  }
});

setScope

Use the hotkeys.setScope method to set scope. There can only be one active scope besides 'all'. By default 'all' is always active.

// Define shortcuts with a scope
hotkeys('ctrl+o, ctrl+alt+enter', 'issues', function() {
  console.log('do something');
});
hotkeys('o, enter', 'files', function() {
  console.log('do something else');
});

// Set the scope (only 'all' and 'issues' shortcuts will be honored)
hotkeys.setScope('issues'); // default scope is 'all'

getScope

Use the hotkeys.getScope method to get scope.

hotkeys.getScope();

deleteScope

Use the hotkeys.deleteScope method to delete a scope. This will also remove all associated hotkeys with it.

hotkeys.deleteScope('issues');

You can use second argument, if need set new scope after deleting.

hotkeys.deleteScope('issues', 'newScopeName');

unbind

Similar to defining shortcuts, they can be unbound using hotkeys.unbind.

// unbind 'a' handler
hotkeys.unbind('a');

// Unbind a hotkeys only for a single scope
// If no scope is specified it defaults to the current 
// scope (hotkeys.getScope())
hotkeys.unbind('o, enter', 'issues');
hotkeys.unbind('o, enter', 'files');

Unbind events through functions.

function example() {
  hotkeys('a', example);
  hotkeys.unbind('a', example);

  hotkeys('a', 'issues', example);
  hotkeys.unbind('a', 'issues', example);
}

To unbind everything.

hotkeys.unbind();

isPressed

For example, hotkeys.isPressed(77) is true if the M key is currently pressed.

hotkeys('a', function() {
  console.log(hotkeys.isPressed('a')); //=> true
  console.log(hotkeys.isPressed('A')); //=> true
  console.log(hotkeys.isPressed(65)); //=> true
});

trigger

trigger shortcut key event

hotkeys.trigger('ctrl+o');
hotkeys.trigger('ctrl+o', 'scope2');

getPressedKeyCodes

Returns an array of key codes currently pressed.

hotkeys('command+ctrl+shift+a,f', function() {
  console.log(hotkeys.getPressedKeyCodes()); //=> [17, 65] or [70]
})

getPressedKeyString

Returns an array of key codes currently pressed.

hotkeys('command+ctrl+shift+a,f', function() {
  console.log(hotkeys.getPressedKeyString()); 
  //=> ['⌘', '⌃', '⇧', 'A', 'F']
})

getAllKeyCodes

Get a list of all registration codes.

hotkeys('command+ctrl+shift+a,f', function() {
  console.log(hotkeys.getAllKeyCodes());
  // [
  //   { 
  //      scope: 'all', 
  //      shortcut: 'command+ctrl+shift+a', 
  //      mods: [91, 17, 16], 
  //      keys: [91, 17, 16, 65] 
  //    },
  //   { scope: 'all', shortcut: 'f', mods: [], keys: [42] }
  // ]
})

filter

By default hotkeys are not enabled for INPUT SELECT TEXTAREA elements. Hotkeys.filter to return to the true shortcut keys set to play a role, false shortcut keys set up failure.

hotkeys.filter = function(event){
  return true;
}
// How to add the filter to edit labels. 
// <div contentEditable="true"></div>
// "contentEditable" Older browsers that do not support drops
hotkeys.filter = function(event) {
  var target = event.target || event.srcElement;
  var tagName = target.tagName;
  return !(
    target.isContentEditable || 
    tagName == 'INPUT' || 
    tagName == 'SELECT' || 
    tagName == 'TEXTAREA'
  );
}

hotkeys.filter = function(event){
  var tagName = (event.target || event.srcElement).tagName;
  hotkeys.setScope(
    /^(INPUT|TEXTAREA|SELECT)$/.test(tagName) ? 'input' : 'other'
  );
  return true;
}

noConflict

Relinquish HotKeys’s control of the hotkeys variable.

var k = hotkeys.noConflict();
k('a', function() {
  console.log("do something")
});

hotkeys()
// -->Uncaught TypeError: hotkeys is not a function(anonymous function)
// @ VM2170:2InjectedScript._evaluateOn
// @ VM2165:883InjectedScript._evaluateAndWrap
// @ VM2165:816InjectedScript.evaluate @ VM2165:682

Development

To develop, Install dependencies, Get the code:

$ git https://github.com/jaywcjlove/hotkeys.git
$ cd hotkeys     # Into the directory
$ npm install    # or  yarn install

To develop, run the self-reloading build:

$ npm run watch

Run Document Website Environment.

# Generate documentation website
$ npm run doc 
# Live-generate documentation website
$ npm run start 

To contribute, please fork Hotkeys.js, add your patch and tests for it (in the test/ folder) and submit a pull request.

$ npm run test
$ npm run test:watch # Development model

Contributors

As always, thanks to our amazing contributors!

Made with action-contributors.

Special thanks to @dimensi for the refactoring of version 4.0.

License

MIT © Kenny Wong