hotkeys-js
v4.0.0-beta.7
Published
A simple micro-library for defining and dispatching keyboard shortcuts. It has no dependencies.
Maintainers
Readme
Hotkeys
HotKeys.js is an input capture library with some very special features, it is easy to pick up and use, has a reasonable footprint (~6kB) (gzipped: 2.8kB), and has no dependencies. It should not interfere with any JavaScript libraries or frameworks. Official document demo preview. More examples.
╭┈┈╮ ╭┈┈╮ ╭┈┈╮
┆ ├┈┈..┈┈┈┈┈.┆ └┈╮┆ ├┈┈..┈┈┈┈┈..┈┈.┈┈..┈┈┈┈┈.
┆ ┆┆ □ ┆┆ ┈┤┆ < ┆ -__┘┆ ┆ ┆┆__ ┈┈┤
╰┈┈┴┈┈╯╰┈┈┈┈┈╯╰┈┈┈┈╯╰┈┈┴┈┈╯╰┈┈┈┈┈╯╰┈┈┈ ┆╰┈┈┈┈┈╯
╰┈┈┈┈┈╯Usage
You will need Node.js installed on your system.
npm install hotkeys-js --saveimport 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
ChromeSupported 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;
}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 activeelement<HTMLElement>: Specifies the DOM element to bind the event tokeyup<Boolean>: Whether to trigger the shortcut on key releasekeydown<Boolean>: Whether to trigger the shortcut on key presssplitKey<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:682Development
To develop, Install dependencies, Get the code:
$ git https://github.com/jaywcjlove/hotkeys.git
$ cd hotkeys # Into the directory
$ npm install # or yarn installTo develop, run the self-reloading build:
$ npm run watchRun 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 modelContributors
As always, thanks to our amazing contributors!
Made with action-contributors.
Special thanks to @dimensi for the refactoring of version 4.0.
