The keyboard navigation module allows users of any Mozilla browser, Windows Internet Explorer 5+, Opera 7+, Safari 1.2+ or Konqueror 3.2+ to navigate the menus with only the keyboard. In other browsers you can still navigate the main bar using Tab and Shift-Tab, or whatever keystrokes you would normally use.
The menus on this site already use this module, but there's also a demo page which includes full instructions you're welcome to copy and use for your own visitors' information.
This site also uses the Keyboard Navigation Help extension, which provides compact instructions to help your visitors navigate with the keyboard. But even with that extension in place you should still provide full instructions somewhere else - such as your accessibility information page.
You probably don't need to download this module, because the default menu zipfile already includes it.
Nonetheless if you need to, you can download the
keyboard navigation script, then
copy it into your udm-resources
folder,
and add the script include to the body section:
<!-- keyboard navigation module -->
<script type="text/javascript"
src="/udm-resources/udm-mod-keyboard.js"></script>
Then add this array to the Modules
section of udm-custom.js
:
//keyboard navigation
um.keys = [
'38', // up ["n"] ("38" = up arrow key)
'39', // right ["n"] ("39" = right arrow key)
'40', // down ["n"] ("40" = down arrow key)
'37', // left ["n"] ("37" = left arrow key)
'123', // hotkey ["n"] ("38" = F12)
'none', // hotkey modifier ["none"|"shiftKey"|"ctrlKey"|"altKey"|"metaKey"]
'27', // escape ["n"|"none"] ("27" = escape key)
'document.getElementsByTagName("a")[0]', // exit focus ["js-expression"]
];
There's more information in the Developer's manual on configuring the um.keys array.
Whatever you set for the hotkey, there's inevitably going to be people who can't use it because their browser has it configured to do something else. There's no way to know, so the thing to do is have a preferences form, and let people change it for themselves. You can see an example of this in the keyboard navigation demo.
The module will still work without it, using the default F12 with no modifier or whatever you've defined in um.keys, but I do recommend it for better accessibility.
So, to implement the preferences form you need two
<select>
elements, as follows:
<select id="modifierSelector">
<option value="none" selected="selected">No modifier</option>
<option value="metaKey">Command [apple] key</option>
<option value="altKey">Alt [option] key</option>
<option value="ctrlKey">Ctrl [control] key</option>
<option value="shiftKey">Shift key</option>
</select>
<select id="hotkeySelector">
<option value="112">F1</option>
<option value="113">F2</option>
<option value="114">F3</option>
<option value="115">F4</option>
<option value="116">F5</option>
<option value="117">F6</option>
<option value="118">F7</option>
<option value="119">F8</option>
<option value="120">F9</option>
<option value="121">F10</option>
<option value="122">F11</option>
<option value="123" selected="selected">F12</option>
</select>
You must not change the id
attributes
"modifierSelector"
and "hotkeySelector"
,
and you must not add or remove any option values.
The code above is not a complete form example - I haven't included a
<form>
, and for
compliance and better accessibility,
each <select>
element should have a
<label>
, and be inside
one or more <fieldset>
. But that's up to you - I'm just
outlining what the script needs.
Anyway, once you have those selectors you need a button
to save the settings, using the onclick
handler to call
a built-in function - um.keyPrefs()
- like this:
<input type="button" onclick="um.keyPrefs()" value="Save settings" />
Even though it's
onclick
, it will still work from the
Enter or Return key.
The um.keyPrefs
function
reads the values from the two selectors,
and saves them to a preferences cookie;
on subsequent visits the cookie values
will be used instead. The cookie itself expires
after one year.
Unsupported browsers will return an alert -
Sorry, this feature is not supported in your browser
.
Supported browsers will return either
Save successful
, or a failure message
if the cookie could not be set.
The button will have no effect in non-javascript browsers - so you should either
generate the form itself in javascript, or
say something explicitly in a <noscript>
section just before it:
<noscript>
<p>
(This form doesn't do anything in
non-javascript browsers)
</p>
</noscript>
The implementation of keyboard navigation varies by browser. The custom hotkey and arrow combinations are available in Mozilla browsers, Windows Internet Explorer 5 or later, and Safari 1.2 or later.
Opera can't be given the custom keystrokes, because they don't completely implement default-action suppression. Users can navigate the menus using the A and Q [anchor navigation] keys, and fairly-successfully using Spatial Navigation (support for spatial navigation is not perfect, but it's pretty good). This functionality also provides compatibility with relevant voice commands in Opera 8, such as "previous/next link", "open link", and the "move" commands of spatial navigation.
Konqueror can't be given the custom keystrokes either,
in this case because event keyCode
values always come back as zero. Users can navigate
the menus using the Tab key.
In Windows Internet Explorer it's possible to use accesskey
attributes
to provide direct triggers to individual menu branches. For example, if
you applied the accesskey "M" to the "Manual" link in the navbar above,
pressing Alt M in
Win/IE would open its menu, which
you could then navigate using the Tab or arrow keys as normal.
This works because Win/IE only sets focus on a link when you use its accesskey
assignment, rather than actuating (clicking) the link,
which is what Mozilla and Opera do.
The difference in behavior is significant, and since the use of accesskeys is debatable anyway, I strongly recommend you don't do this unless you're working for a known user-base - on a public website it would just cause confusion.
UDM 4 is valid XHTML, and in our judgement, meets the criteria for WAI Triple-A conformance.