There are a few good questions on here regarding how to determine where focus goes ‘concurrent’ to a textarea onblur.
But I haven’t found a good cross-browser way to determine which anchor tag has been clicked which caused a textarea to fire onblur, setTimeout or no. document.activeElement looked promising, but, answers seemingly to the contrary, without a setTimeout, activeElement is unreliable. I keep getting the body returned as the activeElement in some browsers.
For example:
jsFiddle-ige #1:
HTML
<form>
<input onblur="blurHandler();" type="text" id="spam1"
value="immediate blur check">
<input onblur="blurHandlerTimeout();" type="text" id="spam2"
value="delayed blur check">
<a href="#" id="spam3">X</a>
<br>
</form>
<br>
<hr>
<br>
<div id="logs"></div>
JavaScript
var logs = document.getElementById('logs');
function blurHandler() {
logit(document.activeElement.outerHTML.substr(0, 80));
}
function blurHandlerTimeout() {
setTimeout(function () {
logit(document.activeElement.outerHTML.substr(0, 80));
}, 10);
}
function logit(msg) {
try {
var e = document.createTextNode(msg), // probably a better way, but this does allow html as text
f = document.createElement('div');
logs.insertBefore(e, logs.firstChild);
logs.insertBefore(f, logs.firstChild);
} catch (err) {
alert(err);
}
}
Body element for blur from the immediate blur check textbox occurs every time for the following:
- Safari 5.1.7 (which doesn’t let me focus on the anchor at all,
tabbing or clicking) - Firefox 18.0.1
- Chrome 24.0.1312.56 m,
Setting focus to the delayed blur check box and clicking/tabbing into the anchor gives me:
- Chrome: the body if click the anchor
- Chrome: the anchor if I tab into it
- Safari: the body either way
- Firefox: the anchor no matter what
IE8 gives me the anchor every time for each textbox, delayed handler or no.
So admittedly there are ways to have the anchor set a boolean at a shared scope level (eg, a global) and have a setTimeout from the blur event query that boolean to see if the anchor [recently] got focus, but man oh man that’s kludgey.
That said, I did it, give or take, here: jsFiddle-ige #2 Seems to work okay there in all four, though I’m afraid it’s going to be edge-case crazy.
Is there better way to do this? jQuery’s fine, I guess, though I’d prefer a clean JavaScript solution — which is to say that a clean jQuery solution is better than convoluted JavaScript fix.
The delayed check for
document.activeElementworks in all browsers as long as you specify atabindexattribute on the anchor tag.a, by default, has no tabbing order, so I’d argue that those browsers that are able to “focus” theaat all without that attribute are misbehaving.Per the HTML5 spec:
(Emphasis mine)
Updated fiddle: http://jsfiddle.net/Y5kcp/4/
Tested in IE8/9, FF 18.0.1, Chrome 24.0.1312.56 m, Safari 5.17
This is pure speculation, but maybe IE was behaving nicely because the HTML4 spec for
tabindexdoesn’t mention “focusability” as a feature:In that case, maybe browsers adhering to the HTML 4 specification are okay allowing the anchor tag to be focusable with or without the tabindex attribute.
It’s also worth noting that
document.activeElementwas a proprietary IE4 feature (see Notes on the MDN article fordocument.activeElement). Maybe that’s why it’ll function without the timeout in Internet Explorer.