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.