78 comments

[ 3.3 ms ] story [ 126 ms ] thread
I don't know if this is on purpose, but the "Cmd+Shift+K" binding is not activated by "Ctrl+Shift+K" or "Alt+Shift+K" on non-Macs. Seems to work great otherwise, though.
Thanks! Command is bound to e.metaKey so whatever that works out to on PC, but you can specify multiple keys like in the next example, by passing an array.
You might consider trying an "accel" alias modifier, so that you don't have to specify both Ctrl and Cmd. That's what Mozilla does: https://developer.mozilla.org/en/XUL_Tutorial/Keyboard_Short...

If you really do want fine-grained control, for example, so that Cmd works on OS X, but it maps to something else entirely on other platforms, you can still use Ctrl and Cmd.

did you try the 'Windows' key?
That doesn't seem to work, either. Besides, Command generally maps to Ctrl/Alt on most pieces of software.
This is why I love the JavaScript community. Tight little library, great API, brilliant project page. Excellent, shiny, hard. work.
They have a big advantage, you know! When you create a jQuery plugin, you can show everyone - instantly. I feel like desktop applications (and even websites, to a degree) don't have that luxury.
Just in case anyone is confused by this comment, though, this isn't a jQuery plugin.
"...brilliant project page..."

even the URL!

craig.is/killing/mice

Very nice! Wrote something like this one too many times in the past, definitely delighted to replace it with a library in the future, thanks! :)
I love you. I really do. This is amazing work.
You know a library (or whatever) is awesome when you're initial reaction is "I can't believe this didn't exist already". I'll definitely be using this!
John Resig's jquery.hotkeys do almost all of it (and it is stable enough, as it is 2 years old): https://github.com/jeresig/jquery.hotkeys
I checked out of curiosity: jquery.hotkeys is about 1.4kb minified, coincidentally the same size as this library. Of course you'd have to add jquery itself to get the total size, if you weren't already using it.
Now there's no excuse to not have a Konami code easter egg on your sites.
I really like the doma.in/name/choice
I wouldn't have noticed it - thanks, made me smile. :)
I can't get "$" or "* a" to activate on my Swedish keyboard, where they're typed option-4 and shift-', respectively.

Dealing with keyboard-shortcuts and international keyboard is hard, I don't think I've ever gotten an app using ctrl-[ to work right.

edit: $ highlights when I type shift-4, while that's actually supposed to produce €

On chrome, 'ctrl-[' triggers a key event with .which, .keyCode, and .charCode all set to 27. 27 is DOM_VK_ESCAPE [1]. On firefox, 'esc' sets .keyCode to 27 [2]. Firefox's 'ctrl-[' sets .which and .charCode to 91 (codepoint for '['), but .keyCode to 0. On both firefox and chrome, plain '[' sets .charCode to 91, as does firefox's 'alt-['. But not 'ctrl-[' on chrome.

   (which,keyCode,charCode)
    
           chrome     firefox
   [       91 91 91   91 0 91
   alt-[   ?          91 0 91
   ctrl-[  27 27 27   91 0 91
   esc     ?          0 27 0
It's one example out of many, but how do you distinguish such cases, short of enumerating the behavior of every browser (and I guess keyboard layout too)?

[1] https://developer.mozilla.org/en/DOM/KeyboardEvent#Virtual_k...

[2] I don't know what chrome does, I couldn't convince it to capture an 'esc' or 'alt-['.

And on my Swedish keyboard you type "[" with alt-8, so when I press ctrl-alt-8, all bets are off.
Thanks for this, I noticed the same thing on chrome with other tools like codepen.io and wasn't able to figure out why it was happening.
The funny thing is that with my keymap (cs_CZ) the 4 and $ keybindings are reversed.
Ditto here on fr_bepo mapping, with chrome 20.0.1132.47.
Nice hack -- I've been going this as inside of backbone.js app. I have a asset management app that uses keyboard shortcuts to quickly tag, choose, and manage photos.

Had I know about this I might have used it rather than bundling it into my views.

Nice work!

It doesn't do modifier key event generation correctly. On a US keyboard, hold down shift and 4 (i.e. type "$"). The second item highlights. Now release shift. The first item highlights, incorrectly, because the library apparently generated a keydown event for "4" when the shift key was released. That's wrong by all standard conventions. Modifier key releases should never synthesize presses.
(comment deleted)
What browser are you using? It works correctly for me using Chrome on Mac. Could you make a ticket on Github?
Chrome 20 on linux. Bug submitted: https://github.com/ccampbell/mousetrap/issues/3
same issue on Win7 / FF13

Also affects the "* a" combo if you release shift before releasing 8 then release 8 and press "a" it doesn't recognize the combination (presumably because its reading a key press of 8 in between them)

I know it doesn't actually say that Opera is supported, but all highlights work, and that little bug he mentioned also occurs in Opera
I think there is no way to change this behavior: https://developer.mozilla.org/en/DOM/KeyboardEvent#Auto-repe...
It's a mess (the core problem is that the X server automatically generates release/press event pairs to implement key repeat which can't affirmatively be detected as "synthetic"). But it's handlable heuristically.

The way I've seen it done it via a timeout on "release after a long press". If the key has been down for more than ~1 second, then hold off on interpreting a release event to see if there's a matching press already queued in the pipe or not. The timeout can be very short (the X server sends them both synchronously down the socket with no delay).

Nice, but could do with a bit of preventDefault love, at least for the examples. Firefox on Linux has Ctrl+Shift+K as Web Console, Ctrl+K as (seemingly) Goto Google.
Ah good idea! I will add those on the demo page later.
(comment deleted)
It's been a while since I last used Firefox, but if I remember correctly, Ctrl/Command-K is a shortcut for your homepage.
My home page is about:newtab. Odd.
On my Firefox, Ctrl-K puts the cursor in the search box. (And on Chromium it puts it in the omnibar with a ? prefilled.)
+1 for the url to the project
This looks like it's doing basically the same thing that keymaster has already been doing, with an almost identical API:

https://github.com/madrobby/keymaster

Everything's already been done everywhere, all the time. Choices are a great thing.
This offers a few additional things such as supporting Gmail style key sequences, binding keyup events, supporting keys that require the shift modifier using their key name "?", triggering key commands programmatically, etc.
Awesome! I'm super excited about this. I've been using keymaster for my Chrome extension for custom key bindings [1] but it's suffering from two issues:

- Lack of "key-sequences" ala Gmail

- Bug where focusing on a page having already pushed down a modifier doesn't tell keymaster that the modifier is pushed. For example if you ctrl+tab to a page and keep the control key pushed, then hit an action key (say "f"), then what you really want is to trigger ctrl+f but keymaster doesn't recognize it because it doesn't see ctrl as having been pressed since it was already held down before the page had focus.

Looks like Mousetrap fixes both of these issues. Thanks a ton!

1: https://chrome.google.com/webstore/detail/logpjaacgmcbpdkdch...

I've found Keymaster good in the past, but the project really isn't being maintained. (https://github.com/madrobby/keymaster/issues?direction=desc&...)

It would be nice to see an ongoing project for this, with keyboard shortcuts becoming more popular (in use at Twitter, GitHub, and Google Plus for example). I'm planning to add the functionality on my own app soon and will take a look at this.

Keymaster has stagnated a bit, that's correct, but it's still a pretty quality piece of work. I'm using it for my own keyboard shortcut (jquery) plugin here : http://joeloliveira.com/chaves.js/demo/defaults.html

The goal of my plugin isn't to just bind keys but to provide sensible defaults and an easy interface to either override the defaults or create your own, as well as have a built-in mechanism to display a "help" modal window. After all, what good are keyboard shortcuts if you don't know what they are.

Check it out. Would love any feedback

(sorry, Craig, for me-too'ing / "hey look at me too"'ing your post).

I really hate pages that take control of the keyboard like this.

Your website isn't so special to completely change how I use my browser.

It might be okay for a game, but in every other case, if my regular bindings don't work, I leave.

I agree. Overwriting the close tab and next/previous tab shortcuts causes me a lot of frustration. Thankfully few webpages do it.
But I think that's the right solution.

For most websites, I will leave. But for web "apps" like Google Docs, or GMail, or my company's internal apps, I want to use application-style keyboard shortcuts like Ctrl+S and Ctrl+T and Ctrl+N. I want Ctrl+N to create a new document inside my application, not a new browser window.

The best solution would be to ask users to give permission to a webpage to overwrite native keyboard shortcuts for their own uses.

Agree, probably the best example where it's okay to offer 'tip' type dialogs on opening the app "We've setup keyboard shortcuts for you, would you like to use them? (examples)". (Saving preferences for future visits).
Great point on using shortcuts on web apps. After a while I forget they on the web and start using shortcuts. This support is welcome.

Great app, project page and effort.

(comment deleted)
On the other hand, this is crucial for things like javascript terminal emulators (which are nice for avoiding the long load time of a java terminal emulator).
The thing is, this isn't a problem space that's unique to web apps. I find nothing more frustrating than native OS X apps that bind over system-wide shortcuts (I'm looking at you, Adobe products). Web apps have a slightly trickier turf to navigate due to also having to watch out for web browser default shortcuts, but that doesn't suddenly make the problem unsolvable.

The problem isn't that keyboard shortcuts for web apps are inherently bad. The problem is application designers who choose their keyboard shortcuts poorly.

Hi craigc, I'd be interested in using this, but (and yeah, this is terrible) I need some sort of "scoping", i.e. hotkeys would dispatch differently based on what element is highlighted.

I realize I could achieve this by making my bound function aware of the scoping, but it would be much nicer to have first class library support (in a library with an already kickass-ly simple API). Any thoughts on this?

One small suggestion is to return Mousetrap from the various methods, so method calls can be chained.

Also, +1 for a reset() command. I recently patched radio.js to do this, and I think it's something many Ajax-style apps need. However, I'm seeing there might be a need to whitelist some bindings as being durable (survive a reset).

Works. Simple and effective with an easy bar for entry. Good job.
Sweet! I can now non-metaphorically dare someone to build a better Mousetrap.
Very nice. I was about to hand roll my own implementation of this, but this just saved me some time :-)

I like how there's a working demo right there on the page - it's nothing groundbreaking but it definitely adds a bit more polish.

Something I'm wondering about - would it pay to have some sort of "variable" key binding whose value would differ depending on the user's OS (if this is even possible)? For example, instead of binding both command+k and ctrl+k, I would bind one combination that would work both on Mac and Windows systems. This isn't a deal breaker or major issue by any means, but I'd be interested to know if it can be done.

> For modifier keys you can use shift, ctrl, alt, option, meta, and command.

No. Just don't. Ever. Unless you are doing a standalone, web based app.

That moment you expect an 'up up down down left right left right B A' easteregg but it's not there... time to fork this T_T