[OpenLayers-Dev] Keyboard navigation and form elements

Gregers Gram Rygg gregersrygg at gmail.com
Wed Jun 10 08:31:17 EDT 2009


Hello all,

As previously discussed, the keyboard-handler is global for the
document, so it captures key events from form elements:
http://trac.openlayers.org/ticket/42
http://trac.openlayers.org/ticket/1027

This is particularly nasty when a user is typing text in an input
field, and use arrows to choose from a auto-suggestion.

I looked into the problem yesterday, and it turns out that Safari, as
the last major browser, added support to document.activeElement in
Safari 4.0 released two days ago. This was a proprietary property in
IE6, but has become the defacto standard in other browsers. I've
successfully tested this in IE6-8, FF3, Opera 9.6, Chrome 2.0.172 and
Safari 4.0. Luckily IE6 already has support, and users of other
browsers update on a more regular basis. So this should be available
on a large majority of users very soon. The best backwards
compatibility option I've found is to add focus and blur events on all
form elements (naaaasty!), and set document.activeElement in the
handler. This should of course only be done if
(!document.activeElement). But I suggest we ignore these users, as
this will not be released before OpenLayers 2.9 in a few months, and
hopefully most Safari users have upgraded by that time.

I have a working prototype, but I want some feedback before I submit
the patch. From my testing of document.activeElement, I've found that
some browsers use whatever node you clicked, and others use the body
object. As far as I know, form elements are the only DOM elements that
can have focus other than the body.

So far I've only added this to KeyboardDefaults.defaultKeyPress :
    if(document.activeElement) {
        var formElements = ["input", "select", "button", "textarea"];
        var tagName = document.activeElement.tagName.toLowerCase();
        for(var i=0,len=formElements.length; i<len; i++) {
            if(tagName == formElements[i]) return; // active element
is a form element
        }
    }

This should probably be extracted to a Util method (Util.isFormElementActive).

Does this seem like the Correct[TM]  solution?
Should this be done in KeybardDefaults or at a higher level?

More details about getting element in focus:
http://stackoverflow.com/questions/497094/how-do-i-find-out-which-javascript-element-has-focus


-Gregers



More information about the Dev mailing list