I am having a hard time finding any documention on what is "suppose" to happen whenever a DOM element is blured.
My naive assumption was that the browser whould traverse up the DOM to find the next focusable element - but given the following jsfiddle, that is obviously not what happens.
<!-- HTML ----------------------------- -->
<body>
<div id="root" tabindex="0">root
<div id="p1" tabindex="0">p1
<div id="p2" tabindex="0">p2
</div>
</div>
</div>
</body>
/* Javascript */
var root = document.getElementById("root");
var p1 = document.getElementById("p1");
var p2 = document.getElementById("p2");
root.addEventListener('keydown', function(event) {
console.log("root keydown");
}, false);
p1.addEventListener('keydown', function(event) {
console.log("p1 keydown");
}, false);
p2.addEventListener('keydown', function(event) {
console.log("p2 keydown - blurring p2, hoping that focus will move up the dom to p1");
event.stopPropagation();
p2.blur();
if (document.activeElement !== p1)
console.log("well, that didn't work out so well :( ");
console.log("focused element = ");
console.log(document.activeElement);
}, false);
p2.focus();
console.log("focused element = ");
console.log(document.activeElement);
So is there a definition of what should happen? What I see happening with Chrome is that the activeElement
jumps to the body
- and skips all of the focusable items along the way. It is unclear if body is even focused, or is just the default handler for activeElement
if nothing else is focused.
Given a complex object-oriented javascript application, in which p2 does not know about p1, but assumes that anything higher up in the DOM will gain focus, am I really suppose to manually traverse up the DOM on every blur()
event and search for focusable elements and focus them myself?
The closest thing to a specification about this is probably the description of focus in HTML5 CR (which is work in progress, “a draft document and may be updated, replaced or obsoleted by other documents at any time”, but in practice close to a consensus). It says: “There may be no element focused; when no element is focused, key events received by the document must be targeted at the body element, if there is one, or else at the Document's root element, if there is one. If there is no root element, key events must not be fired.”
Since the
blur()
method is defined (in DOM 2 HTML spec) simply as removing focus, it means leaving a page in a state where no element is focused. But this may look like thebody
element were focused: if you have, say, akeypress
attribute on it, it gets triggered. This however differs from the focused state. For example, in this situation, thebody
element does not match the CSS selector:focus
.The conclusion is that you should normally avoid using
blur()
and dofocus()
on some suitable focusable element instead, as suggested in other answers. An exception is a situation where you just want to discard all keyboard events. Thenblur()
is OK, provided that your code does not assign any keyboard event handlers to thebody
element.If you just want to make sure that one element gets focused when another gets blurred:
Fiddle: http://jsfiddle.net/2cWcA/
You could extend this so that when any element is blurred, it's parent's
focus
method is called.My understanding is that
blur
just means unfocus. In other words, the focused element loses focus, and it's undefined what, if anything, gains focus. The fact thatactiveElement
becomesbody
is probably just a side effect. Rather than setting it tonull
it's set to the body, to indicate that the document in general still has focus.Actually document.ActiveElement() focuses an element. In javascript focus is done like
document.getElementById('myAnchor').focus()
MoreOver the focus event triggers when a visitor focuses on an element.Not all elements are focusable by default. For example, INPUT and all types or form fields support this event, A supports it. As a counterexample, DIV doesn’t support focus.
The list of elements types which support focusing is slightly different between browsers.
Thanks