First, they have different meaning: they fire:
- KeyDown – when a key was pushed down
- KeyUp – when a pushed button was released, and after the value of input/textarea is updated (the only one among these)
- KeyPress – between those and doesn't actually mean a key was pushed and released (see below). Not only it has inconsistent semantics, it was deprecated, so one shouldn't probably use it (see also this summary)
Second, some keys fire some of these events and don't fire others. For instance,
- KeyPress ignores delete, arrows, PgUp/PgDn, home/end, ctrl, alt, shift etc while KeyDown and KeyUp don't (see details about esc below);
- when you switch window via alt+tab in Windows, only KeyDown for alt fires because window switching happens before any other event (and KeyDown for tab is prevented by system, I suppose, at least in Chrome 71).
Also, you should keep in mind that event.keyCode
(and event.which
) usually have same value for KeyDown and KeyUp but different one for KeyPress. Try the playground I've created. By the way, I've noticed quite a quirk: in Chrome, when I press ctrl+a and the input
/textarea
is empty, for KeyPress fires with event.keyCode
(and event.which
) equal to 1
! (when the input is not empty, it doesn't fire at all).
Note: these days, using event.key
and event.code
are the most useful options as it is standardized across browsers, OSes and events (afaik), while event.which
and event.keyCode
are deprecated (1, 2).
Finally, there's some pragmatics:
- For handling arrows, you'll probably need to use onKeyDown: if user holds ↓, KeyDown fires several times (while KeyUp fires only once when they release the button). Also, in some cases you can easily prevent propagation of KeyDown but can't (or can't that easily) prevent propagation of KeyUp (for instance, if you want to submit on enter without adding newline to the text field).
- Suprisingly, when you hold a key, say in
textarea
, both KeyPress and KeyDown fire multiple times (Chrome 71), I'd use KeyDown if I need the event that fires multiple times and KeyUp for single key release.
- KeyDown is usually better for games when you have to provide better responsiveness to their actions.
- esc is usually processed via KeyDown: KeyPress doesn't fire and KeyUp behaves differently for
input
s and textarea
s in different browsers (mostly due to loss of focus)
- If you'd like to adjust height of a text area to the content, you probably won't use onKeyDown but rather onKeyPress (PS ok, it's actually better to use onChange for this case).
I've used all 3 in my project but unfortunately may have forgotten some of pragmatics. (to be noted: there's also input
and change
events)