The Google Maps API (v1) has most of this, but doesn't expose it to user level, and especially not so with real names for identifiers, documentation or any other bits to make it usable for an applications level developer.
To interface the keyboard as a control device for an application, you basically want these features:
keydown
,keyup
andkeypress
event callbacks for specific keys,keypress
being fired on consecutivekeydown
andkeyup
events for the key in question, and not being fired by the host operating system's keyrepeat features- not triggering said callbacks when some text input field has keyboard focus
- a query method to ask whether a specific key is in pressed down now.
- a query method to ask what keys are in pressed down state now
- a symbolic key name handling abstraction, to rid your code of unreadable key code constants
- additional bonus points for allowing polling consumption of keypress events rather than just by way of fired callbacks right when the event is fired
Google Maps is an excellent example of an application that makes good use for these controls. When run with keyboard controls on, you can pan the map using the arrow keys, for instance, or whole pages using Page Up, Page Down, Home and End. (The Maps API does not enable this by default, but you can add them fairly easily add it -- if I remember correctly, it's done using
map.registerKeyHandlers(window.document)
.)A naïve implementation, registering with the DOM to receive
keypress
all events, would buffer up a busload of keypresses (due to key repeat, as set up in the end user's operating system) when a user keeps an arrow key down to scroll the map continuously, and keep processing queued-up events for some length of time after the user releases the key, which is clearly not what you want. Similarly, an application for a set top box interface I wrote at work last year, where icons scroll into view on pressing the remote control keys for "next" and "previous", had the same problem:- If you tap a key four times, you expect an action to be performed four times.
- If you keep a key pressed, you expect some action to be performed continuously until you let go of the key
Pressing right or left scrolls the next icon into focus, rolling the line of icons one step in either direction. When in a "moving" state, we react instantly to events that would reverse scroll direction, but do not process events that would move in the same direction again, until the completion of one move step. When there, we consume a keypress, if enqueued, or keep scrolling, if we were told that the key is still in a pressed state. If no keys were on the input queue, and no key was still pressed down, we stop scrolling at the icon we ended up on.
As always, the best way of encouraging the broad masses to do good user interface design, is to show how it's done, and to make doing it really easy. The first is what tutorials and articles (such as this one) do, the second what libraries do. (Finally, making it possible at all is what the W3C does.) Your help in bringing about better overall design of new things coming is greatly appreciated, whichever end of the spectrum you contribute to.