Detecting keystrokes

iCab doesn't support the key events at all.

Many thanks to Hallvord Steen for his summary of the key events in Windows browsers; his page saved me quite a bit of work.

Detecting the user's keystrokes turns out to be a rather specialised branch of event handling. This page details some of the more obnoxious problems, and gives the inevitable compatibility table.

The first problem is that there is no standard for key events; the specification says:

An event module designed for use with keyboard input devices will be included in a later version of the DOM specification.

As we all know, browser vendors start experimenting when there's no official standard, and these experiments, though occasionally useful, also cause incompatibilities. The key events are no exception: there are currently two properties that give information about the pressed keys, and although there's some justification for this duplication, not all browsers support them in the same way.

In addition, there are a few important differences between the keydown and keyup events on one hand, and the keypress event on the other.

Finally, there are important differences between Windows and Mac. In general, detecting keys on Mac is much, much more difficult than on Windows.

keyCode and charCode

The two properties are keyCode and charCode. Put (too) simply, keyCode says something about the actual keyboard key the user pressed, while charCode gives the ASCII value of the resulting character. These bits of information need not be the same; for instance, a lower case 'a' and an upper case 'A' have the same keyCode, because the user presses the same key, but a different charCode because the resulting character is different.

Explorer and Opera do not support charCode. However, they give the character information in keyCode, but only onkeypress. Onkeydown and -up keyCode contains key information.

Alphanumeric keys

Let's start with a simple example. The lower case 'a' has ASCII value 97, while the upper case 'A' has ASCII value 65. In both cases the user presses the same key on the keyboard, which has key code 65 (equal to upper case ASCII, as you see).

keyCode

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
keydown or keyup

Theory: Key code

Yes Yes Yes Yes Yes

The only case that all browsers agree on.

keypress

Theory: ASCII

Yes Incorrect Yes Yes Yes
  • Firefox always gives 0

charCode

Method or property IE 5.5 IE 6 IE 7 IE8b1 FF 2 FF 3b5 Saf 3.0 Win Saf 3.1 Win Opera 9.26 Opera 9.5b Konqueror 3.5.7
keydown or keyup

Theory: 0

No Yes Incorrect Yes No Yes
  • Safari 3.0 returns the ASCII value.
keypress

Theory: ASCII

No Yes Yes No Yes

Therefore, onkeydown/up keyCode always holds the key code. onkeypress you can find the actual character the user typed by evt.charCode || evt.keyCode.

Punctuation keys

I decided not to test the punctuation keys. I suspect that these keys are dependant not only on browser and operating system, but also on keyboard configuration and the official system language. I work on a Dutch Windows, but with a US 101 keyboard configuration, and I wouldn't be surprised if that matters a lot in punctuation keys experiments.

For instance, shift + , causes a < character to appear in my applications, but the ASCII value returned by my test script belongs to the ?. When I discovered that I decided not to risk my sanity by performing further punctuation character experiments.

Special keys

The special keys encompass all those keys that don't cause a character to appear, but execute a certain function. For instance, shift, escape, pageDown, and enter are all special keys.

Some general caveats:

If you need to detect these keys, do yourself a favour and search for their keyCode onkeydown/up, and ignore both onkeypress and charCode.

Property Explorer 5-7 Firefox 2.0 Windows Firefox 2.0 Mac Safari 1.3 Opera 9 Windows Opera 9 Mac
alt: 18
The keypress event does not fire
Yes Yes No No Incomplete Yes

Opera on Mac also fires the keypress event, but does not repeat. Opera on Windows fires a keyup event only the second time you press the key (when the focus is removed from the browser toolbar).

arrow keys: 37-40
37: left
38: up
39: right
40: down
The keypress event does not fire
Yes Yes Yes Almost Yes Yes

The keypress event fires in Safari and Opera. However, onkeypress Safari gives very weird keyCodes: 63232-5, and the order doesn't coincide with the normal key order.

backspace: 8
Yes Yes Yes Yes Yes Yes

The single key that's supported exactly the same by all browsers.

caps lock: 20
The keypress event does not fire
Yes Yes No No Yes No

Undetectable on Mac, even in Opera.

cmd
Mac only
Untestable Untestable No No Untestable 17

Only Opera detects this key, but gives it a keyCode of 17, which is usually reserved for the Ctrl key.

Property Explorer 5-7 Firefox 2.0 Windows Firefox 2.0 Mac Safari 1.3 Opera 9 Windows Opera 9 Mac
ctrl: 17
The keypress event does not fire
Yes Yes No No Yes Incorrect

Opera Mac gives keyCode 0.

delete: 46
Almost Yes Yes Almost Yes Yes

Explorer doesn't fire the keypress event.

Safari gives keyCode 63272 onkeypress.

end: 35
Almost Yes Yes Almost Yes Yes

Explorer doesn't fire the keypress event.

Safari gives keyCode 63275 onkeypress.

enter: 13
Almost Yes Yes Yes Yes Yes

Explorer doesn't fire the keypress event.

escape: 27
Almost Yes Yes Yes Yes Yes

Explorer doesn't fire the keypress event.

Property Explorer 5-7 Firefox 2.0 Windows Firefox 2.0 Mac Safari 1.3 Opera 9 Windows Opera 9 Mac
f1 - f12: 112-123
Almost Yes Yes Almost Yes Incorrect

Explorer doesn't fire the keypress event.

Safari gives keyCodes 63236-47 onkeypress.

Opera Mac only gives the correct keyCode onkeypress; onkeydown and -up it's 0.

help
Mac only
Untestable Untestable 6 45 Untestable 5 or 63

Safari fires only the keyup event.

Opera gives 5 onkeydown and -up; 63 onkeypress.

home: 36
Almost Yes Yes Almost Yes Yes

Explorer doesn't fire the keypress event.

Safari gives keyCode 63273 onkeypress.

insert: 45
Almost Yes Untestable Untestable Yes Untestable

Explorer doesn't fire the keypress event.

Property Explorer 5-7 Firefox 2.0 Windows Firefox 2.0 Mac Safari 1.3 Opera 9 Windows Opera 9 Mac
num lock: 144
The keypress event does not fire
Yes Yes 12 12 Yes 27

Chaos on Mac. Mozilla and Safari give 12, Opera 27.

Safari gives 63289 onkeypress.

page up / down: 33-34
Almost Yes Yes Almost Yes Yes

Explorer doesn't fire the keypress event.

Safari gives keyCode 63276-7 onkeypress.

shift: 16
Yes Yes No No Yes Yes

Not in Mozilla Mac and Safari.

tab: 9
Almost Yes Yes Yes Yes Yes

Explorer doesn't fire the keypress event.

windows (start): 91
Windows only
The keypress event does not fire
Yes Yes Untestable Untestable Yes Untestable

Mozilla also fires the keypress event.

Property Explorer 5-7 Firefox 2.0 Windows Firefox 2.0 Mac Safari 1.3 Opera 9 Windows Opera 9 Mac

Test