James Aylett: Accessibility Advent: beware focus events, redux

Published at
Tuesday 18th December, 2012

(Throughout Advent I’m sharing some hints as to how web developers can make my life as a speech recognition user easier.)

I wrote previously about being wary of the blur event; this hint is kind of the opposite. When you’re binding keystroke event handlers, be very careful about where you bind them to. This, at least, is what I think is happening with Google Instant.

If you have a reasonably modern computer you’ll see Instant working: on a Google results page if you type changes to your search and Google is confident that the results match what you’re looking for then the results will be updated “instantly”.

I have to turn it off. (All credit to Google for making this possible.)

The problem is that Instant interacts poorly with Glee Box; if I bring up Glee Box (typically by pressing g) then anything I “type” into it also gets added to the Google search box. Then Instant kicks in a couple of seconds later and completely changes the search results (it also usually removes the Glee Box, for some reason).

Probably because Google uses the Google Web Toolkit extensively, it’s a bit too difficult to dig into it and figure out what’s actually going on here. But what I think is happening is that keystrokes are being captured by Google globally, probably using a handler on the document object. These are then manually being added to the search box, even if they were typed into something else. I may be completely misrepresenting what is going on, because that’s frankly insane.

There are situations where you want a keystroke handler bound to the document object; global keystrokes can be used to implement keyboard shortcuts in a web application, for instance. Google needs this on the search results page to implement keyboard navigation for search results. (Arrow keys moving through the different matches, for instance.) However when you want to do something clever with text typed into a specific box, you should be careful to make your handler only respond to keystrokes for the input element. (jQuery has a way of binding a keystroke handler to one element, but having it only respond to keystrokes from child elements matching a selector, which may help here.) Alternatively, you may be able to use a change event on the input element instead.

I’m not really convinced that Google is doing what I’ve outlined above; for instance, there seems to be a keyboard handler on the input element as well as on the document object. But whether they are or not, you should definitely be careful if building something similar.