6

What's the most robust way of creating a global keyboard shortcut handler for a Web application using JavaScript i.e. which event(s) should I handle and what should the event handler(s) be attached to?

I want something like the system in Gmail which can handle both single keypress shortcuts and also shortcuts with modifier keys e.g. Ctrl + B etc. The code has to work in IE 6 as well as modern browsers.

I have the Prototype framework available to use but not jQuery, so please, no jQuery-specific answers!

Rob W
  • 341,306
  • 83
  • 791
  • 678
John Topley
  • 113,588
  • 46
  • 195
  • 237

6 Answers6

6

Just thought I'd throw another into the mix. I recently released a library called Mousetrap. Check it out at http://craig.is/killing/mice

Craig
  • 2,684
  • 27
  • 20
5

The HotKey library available in the LivePipe controls package works with Prototype and is IE compatible.

http://livepipe.net/extra/hotkey

james
  • 299
  • 1
  • 5
  • I'm going to accept your answer because this looks like exactly what I'm looking for and because there's lots of other interesting stuff on that site, so thanks! – John Topley Mar 04 '09 at 21:17
  • Be warned, HotKey apparently accepts combinations if unspecified modifiers are pressed (eg. specified ctrl + a, pressed ctrl + shift + a, the ctrl + a is detected). – eyelidlessness Mar 06 '09 at 09:18
  • It would also be nice if it detected OS X and replaced ctrl with cmd/meta. – eyelidlessness Mar 06 '09 at 09:20
4

JimmyP posted this as a comment, but it deserves to be an answer for voting purposes.

http://www.openjs.com/scripts/events/keyboard_shortcuts/

eyelidlessness
  • 62,413
  • 11
  • 90
  • 94
3

What I would do is attach onKeyUp events to the document.body. Then, in this event handler, I would use the Element.fire method to fire a custom event. Though this step is optional, it will help in decoupling the event handler from the action to be performed, and you can use the same custom-event handler from say an button click event.

$(document.body).observe("keyup", function() {
    if(/* key + modifier match */) {
        $(document.body).fire("myapp:mycoolevent");
    }
});

$(document.body).observe("myapp:mycoolevent", function() {
    // Handle event.
});

Later, to bind the same event to a button click:

$(button).observe("click", function() {
    $(document.body).fire("myapp:mycoolevent");
});

As far as handling modifier keys is concerned, check out this resource (very old, but still looks applicable) for more help.

Rakesh Pai
  • 26,069
  • 3
  • 25
  • 31
  • Keyup seems problematic. At least on OS X (but I believe it's true on Windows and most Linux WMs as well), most key commands activate on keydown. This expectation (with proper checking) also enforces certain expectations on shortcuts: modifier keys must be first, only one printable key per shortcut. – eyelidlessness Mar 06 '09 at 09:23
2

There is also new JavaScript library called jwerty, it's easy to use and doesn't rely on jQuery.

Keithamus
  • 1,819
  • 17
  • 21
Dawid Woźniak
  • 198
  • 1
  • 9
0

I recommend having a look at Keystrokes. It makes this sort of thing extremely easy.

import { bindKey, bindKeyCombo } from '@rwh/keystrokes'

bindKey('a', () =>
  console.log('You\'re pressing "a"'))

bindKeyCombo('ctrl > y, r', () =>
  console.log('You pressed "ctrl" then "y", released both, and are pressing "r"'))
Robert Hurst
  • 8,902
  • 5
  • 42
  • 66