• Stars
    star
    6,525
  • Rank 6,069 (Top 0.2 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 13 years ago
  • Updated 4 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A simple micro-library for defining and dispatching keyboard shortcuts. It has no dependencies.

keymaster.js

Keymaster is a simple micro-library for defining and dispatching keyboard shortcuts in web applications.

It has no dependencies.

It’s a work in progress (e.g. beta), so spare me your nerdrage and instead contribute! Patches are welcome, but they are not guaranteed to make it in.

Usage

Include keymaster.js in your web app*, by loading it as usual:

<script src="keymaster.js"></script>

Keymaster has no dependencies and can be used completely standalone. It should not interfere with any JavaScript libraries or frameworks.

*Preferably use a minified version that fits your workflow. You can run make to have UglifyJS (if you have it installed) create a keymaster.min.js file for you.

Defining shortcuts

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

// define short of 'a'
key('a', function(){ alert('you pressed a!') });

// returning false stops the event and prevents default browser events
key('ctrl+r', function(){ alert('stopped reload!'); return false });

// multiple shortcuts that do the same thing
key('⌘+r, ctrl+r', function(){ });

The handler method is called with two arguments set, the keydown event fired, and an object containing, among others, the following two properties:

shortcut: a string that contains the shortcut used, e.g. ctrl+r scope: a string describing the scope (or all)

key('⌘+r, ctrl+r', function(event, handler){
  console.log(handler.shortcut, handler.scope);
});

// "ctrl+r", "all"

Supported keys

Keymaster 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 and f1 through f19.

Modifier key queries

At any point in time (even in code other than key shortcut handlers), you can query the key object for the state of any keys. This allows easy implementation of things like shift+click handlers. For example, key.shift is true if the shift key is currently pressed.

if(key.shift) alert('shift is pressed, OMGZ!');

Other key queries

At any point in time (even in code other than key shortcut handlers), you can query the key object for the state of any key. This is very helpful for game development using a game loop. For example, key.isPressed(77) is true if the M key is currently pressed.

if(key.isPressed("M")) alert('M key is pressed, can ya believe it!?');
if(key.isPressed(77)) alert('M key is pressed, can ya believe it!?');

You can also get these as an array using...

key.getPressedKeyCodes() // returns an array of key codes currently pressed

Scopes

If you want to reuse the same shortcut for separate areas in your single page app, Keymaster supports switching between scopes. Use the key.setScope method to set scope.

// define shortcuts with a scope
key('o, enter', 'issues', function(){ /* do something */ });
key('o, enter', 'files', function(){ /* do something else */ });

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

// remove all events that are set in 'issues' scope
key.deleteScope('issues');

Filter key presses

By default, when an INPUT, SELECT or TEXTAREA element is focused, Keymaster doesn't process any shortcuts.

You can change this by overwriting key.filter with a new function. This function is called before Keymaster processes shortcuts, with the keydown event as argument.

If your function returns false, then the no shortcuts will be processed.

Here's the default implementation for reference:

function filter(event){
  var tagName = (event.target || event.srcElement).tagName;
  return !(tagName == 'INPUT' || tagName == 'SELECT' || tagName == 'TEXTAREA');
}

If you only want some shortcuts to work while in an input element, you can change the scope in the key.filter function. Here's an example implementation, setting the scope to either 'input' or 'other'. Don't forget to return true so the any shortcuts get processed.

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

However a more robust way to handle this is to use proper focus and blur event handlers on your input element, and change scopes there as you see fit.

noConflict mode

You can call key.noConflict to remove the key function from global scope and restore whatever key was defined to before Keymaster was loaded. Calling key.noConflict will return the Keymaster key function.

var k = key.noConflict();
k('a', function() { /* ... */ });

key()
// --> TypeError: 'undefined' is not a function

Unbinding shortcuts

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

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

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

Notes

Keymaster should work with any browser that fires keyup and keydown events, and is tested with IE (6+), Safari, Firefox and Chrome.

See http://madrobby.github.com/keymaster/ for a live demo.

CoffeeScript

If you're using CoffeeScript, configuring key shortcuts couldn't be simpler:

key 'a', -> alert('you pressed a!')

key '⌘+r, ctrl+r', ->
  alert 'stopped reload!'
  off

key 'o, enter', 'issues', ->
  whatevs()

alert 'shift is pressed, OMGZ!' if key.shift

Contributing

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

TODOs

  • Finish test suite

Keymaster is (c) 2011-2013 Thomas Fuchs and may be freely distributed under the MIT license. See the MIT-LICENSE file.

More Repositories

1

zepto

Zepto.js is a minimalist JavaScript library for modern browsers, with a jQuery-compatible API
HTML
14,992
star
2

scriptaculous

script.aculo.us is an open-source JavaScript framework for visual effects and interface behaviours.
HTML
2,321
star
3

vapor.js

The World's Smallest & Fastest JavaScript Library
JavaScript
1,373
star
4

dom-monster

JavaScript
562
star
5

emile

emile.js is a no-frills stand-alone CSS animation JavaScript framework, named after Γ‰mile Cohl, early animator.
JavaScript
530
star
6

scripty2

scripty2: for a more delicious web
JavaScript
516
star
7

pragmatic.js

Pragmatic rules for writing JavaScript
381
star
8

textorize

Ruby
236
star
9

semicolon.js

A more secure. stable and reliable version of vapor.js
JavaScript
229
star
10

zaru

Filename sanitization for Ruby
Ruby
222
star
11

creditcard_js

A creditcard validation library for JavaScript using Prototype
JavaScript
184
star
12

downtime

Standardized JSON API to indicate downtime for apps and services
JavaScript
90
star
13

prototype_helpers

Various bits and helpers for Prototype and scriptaculous, that might prove useful or not. :)
JavaScript
75
star
14

bitarray.js

Pure JavaScript bit array/bitfield implementation
JavaScript
53
star
15

spark_pr

Pure Ruby sparklines.
Ruby
42
star
16

purrson-icon

39
star
17

creditcard_js_underscore

A port of creditcard_js to underscore.js
JavaScript
23
star
18

secure.js

JavaScript
20
star
19

jive

HTML
17
star
20

js-animation-course

JavaScript
16
star
21

gifs

Shell
15
star
22

box2d-js

Sprocketized version of box2jd-js
JavaScript
12
star
23

blink

12
star
24

zeptojs.com

JavaScript
12
star
25

dotvim

Vim Script
11
star
26

ponymizer

Generator of random pony names to be used as friendly and fun test data
Ruby
10
star
27

js1k-finals

7
star
28

jslogocrazyness

6
star
29

madrobby.github.com

5
star
30

acornkittens

JavaScript
5
star
31

yotta

A heavily-optimized JavaScript library with a large impact
HTML
5
star
32

plastic-clock

CSS
3
star
33

schnitzelconf-intro

1
star