# ally.when.key
Executes a callback when a given key has been pressed.
# Description
This is a convenience API to avoid adding and removing keyboard event handlers and having to filter for specific keys in application code. Callbacks are executed synchronously while handling keydown
events to maintain the ability to event.preventDefault()
.
Keyboard events are dispatched to the currently focused element (document.activeElement
). This allows us to handle keyboard events only when the user is engaged in a particular widget.
# Key binding syntax
In order to easily register keyboard events including modifier keys, ally.when.key
understands the following <key-binding>
syntax:
<key-binding> |
primary key | keyCode | alt | ctrl | meta | shift |
---|---|---|---|---|---|---|
space |
Space | 32 | no | no | no | no |
*+space |
Space | 32 | ? | ? | ? | ? |
shift+space |
Space | 32 | no | no | no | yes |
shift+*+enter |
Enter | 13 | ? | ? | ? | yes |
!shift+*+enter |
Enter | 13 | ? | ? | ? | no |
?shift+ctrl+enter |
Enter | 13 | no | yes | no | ? |
enter shift+8 |
Enter | 13 | no | no | no | no |
(continued) | Backspace | 8 | no | no | no | yes |
Legend: no
means the modifier key is not pressed, yes
means the modifier key is pressed, ?
means the state of the modifier key is ignored.
The <key-binding>
syntax is defined by the following EBNF grammar, with property of map/keycode
referring to the property names of ally.map.keycode
:
token-list = token, { " ", token } ;
token = { modifier, "+" }, key ;
key = named-key | keycode ;
named-key = ? property of ally.map.keycode ? ;
keycode = ? /[0-9]+/ ? ;
modifier = ( [ "!" | "?" ], modifier-name ) | "*" ;
modifier-name = "alt" | "ctrl" | "meta" | "shift" ;
# Modifier keys
The modifier keys may have different names/symbols depending on operating system and physical keyboard:
modifier key name | physical key on keyboard |
---|---|
alt | Alt, Option or ⌥ on Mac) |
ctrl | Ctrl, ⌃ on Mac |
meta | Meta, ⌘ or or Command on Mac, ⊞ or Windows on Windows |
shift | Shift, ⇧ on Mac |
# Usage
var handle = ally.when.key({
enter: function(event, disengage) {
// react to <kbd>Enter</kbd>
console.log('enter pressed on', event.target);
disengage();
},
32: function(event, disengage) {
// react to <kbd>Space</kbd>
console.log('space pressed on', event.target);
},
});
handle.disengage();
# Arguments
Name | Type | Default | Description |
---|---|---|---|
context | <selector> |
documentElement |
The scope of the DOM in which keyboard events will be processed. The first element of a collection is used. |
filter | <selector> |
null |
The elements and descendants to exclude when processing keyboard events. |
<key-binding> |
function | required | Mapping of <key-binding> to callback function. See Callback Signature for details. This argument is expected one or more times. |
# Returns
A <service>
interface, providing the handle.disengage()
method to stop the service.
# Throws
TypeError
if no<key-binding>: <callback>
combinations were passed.TypeError
if<key-binding>
does not resolve to a keyCode.TypeError
if<key-binding>
contains illegal modifier names.TypeError
if<callback>
is not afunction
.
# Callback signature
Name | Type | Default | Description |
---|---|---|---|
event | KeyboardEvent |
required | The original keydown event. |
disengage | function | required | The service's handle.disengage() method. |
The callback is executed in the context of context
(that's where this
inside the callback points to). The callback is passed the handle.disengage()
method to allow simplified "execute once" behaviors. The callback's return value is ignored.
# Examples
# ally.when.key Example
play with ally.when.key Example on jsbin.com or open the document of ally.when.key Example
# Changes
v1.1.0
introduced the extended<key-binding>
syntax (thereby changing the default modifier key behavior).v1.1.0
introduced the optionscontext
andfilter
.
# Notes
Firefox has a long standing issue with keyboard events propagating to the document while browser UI like autocomplete is being interacted with Gecko 286933.
The callback for the <key-binding>
space
only executes if no modifier key was pressed. In order to make the callback execute regardless of modifier keys, use the <key-binding>
*+space
.
The modifiers alt
, ctrl
, meta
usually engage system-level or browser-level functionality. Do not use these modifiers lightly. For example alt+a
prints the letter å
on a Mac with German keyboard layout, meta+q
exits the application and meta+space
engages Spotlight.
# Related resources
ally.map.keycode
used for resolving named keys- The
<key-binding>
syntax is inspired by PolymerElements/iron-a11y-keys
# Contributing
- module source
- document source
- unit test
- uses when/key.binding to parse
<key-binding>