
Mousetrap: Keyboard shortcuts in Javascript - jasonmoo
http://craig.is/killing/mice
======
kalleboo
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 €

~~~
uvdiv
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...](https://developer.mozilla.org/en/DOM/KeyboardEvent#Virtual_key_codes)

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

~~~
kalleboo
And on my Swedish keyboard you type "[" with alt-8, so when I press ctrl-
alt-8, all bets are off.

------
nilliams
This is why I love the JavaScript community. Tight little library, great API,
brilliant project page. Excellent, shiny, hard. work.

~~~
prezjordan
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.

~~~
exogen
Just in case anyone is confused by this comment, though, this isn't a jQuery
plugin.

------
ajross
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.

~~~
craigc
What browser are you using? It works correctly for me using Chrome on Mac.
Could you make a ticket on Github?

~~~
ajross
Chrome 20 on linux. Bug submitted:
<https://github.com/ccampbell/mousetrap/issues/3>

~~~
craigc
Thank you.

~~~
craigc
I wonder if this is related to
<https://github.com/ccampbell/mousetrap/issues/6>

In which case it should be a pretty painless fix.

------
mmahemoff
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).

~~~
craigc
Please make tickets at <https://github.com/ccampbell/mousetrap/issues>

------
jlarocco
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.

~~~
crazygringo
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.

~~~
nilliams
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).

------
quarterto
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.

~~~
josso
It's been a while since I last used Firefox, but if I remember correctly,
Ctrl/Command-K is a shortcut for your homepage.

~~~
dbaupp
On my Firefox, Ctrl-K puts the cursor in the search box. (And on Chromium it
puts it in the omnibar with a ? prefilled.)

------
TimJRobinson
Dear Asana, Evernote and all other text editing web apps: Can you please use
this library to add ctrl + s = save support. I hit it so frequently during
writing out of habit and every time I do so Chrome asks me to save the website
out as a html file. Thanks! :)

------
bratsche
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>

~~~
craigc
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.

~~~
mcrittenden
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...](https://chrome.google.com/webstore/detail/logpjaacgmcbpdkdchjiaagddngobkck)

------
modarts
I really like the doma.in/name/choice

~~~
loceng
I wouldn't have noticed it - thanks, made me smile. :)

------
achal
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.

~~~
craigc
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.

~~~
mozillarewind
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...](https://developer.mozilla.org/en/XUL_Tutorial/Keyboard_Shortcuts)

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.

------
Keithamus
This looks very similar to a library I created/am working on:
<http://keithcirkel.co.uk/jwerty/>

------
tantalor
This might make more sense as a object model rather than class model. There is
a lot of state behind the scenes (bind, trigger, reset), which would be
natural for an object. Instead it is dumped into global state.

The use case might be to support multiple sets of key bindings, e.g., default,
user specific, app specific, view specific. When you don't need one set
anymore you just "reset" that set instead of resetting everything.

------
jonny_eh
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!

~~~
DanielRibeiro
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>

~~~
morsch
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.

------
arms
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.

------
andreyf
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! :)

------
tych0
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?

~~~
craigc
I'm not sure if I want to support this or not. Please make a ticket over at
<https://github.com/ccampbell/mousetrap>

~~~
mrtron
Perhaps some documentation on how to handle scoping with the callbacks is
adequate.

------
drewmclellan
This looks really useful, and the API looks simple.

Just a quick reminder for those using any library like this; screenreader
users (typically blind people) rely heavily on the keyboard to use their web
browser. Adding your own shortcuts can really screw them over. It's usually
best to make your custom shortcuts a feature that the user opts in to, off by
default.

------
Suan
If anyone is looking for a way to let users enter keycombos which you could
then use with Mousetrap, I wrote this: <http://suan.github.com/jquery-
keycombinator/>

------
sheraz
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!

~~~
shiftb
I'd love to see this integrated into Backbone. Bindings could be specified in
a keyboard_events hash similar to how the existing events hash is run.

~~~
shiftb
Ok, so I just did it: <https://github.com/shiftb/backbone-mousetrap>

------
mihok
+1 for the url to the project

------
danso
Now there's no excuse to not have a Konami code easter egg on your sites.

------
wildmXranat
Works. Simple and effective with an easy bar for entry. Good job.

------
lubomir
The funny thing is that with my keymap (cs_CZ) the 4 and $ keybindings are
reversed.

~~~
Aissen
Ditto here on fr_bepo mapping, with chrome 20.0.1132.47.

------
freshlog
Sweet! I can now non-metaphorically dare someone to build a better Mousetrap.

------
bussetta
Shouldn't it be download it and throw away your mouse? ;)

------
kxhitiz
This is awesome library. Thumbs up for the post.

------
Killswitch
I love you. I really do. This is amazing work.

------
drudru11
it needs gmail like 'help' screen

------
J2triplezero
awesome!

------
rplnt
> 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.

