Friday, August 29, 2008

element.hasFocus? document.activeElement!

Today at work, in some code I was writing, I wanted to know if a given input box has focus or not. Turned out, this is surprisingly difficult. The input element doesn't have any hasFocus or similar property! No wonder working with the DOM keeps tripping people up!

Turns out, from quite some time now, Internet Exploder has been supporting a proprietary property - document.activeElement - which tells you which element is current focussed. Exactly what I needed. Except this is proprietary - I tried in Firefox 2, and it didn't work as expected. However, fortunately, turns out the HTML 5 spec has now incorporated this new property of the document object, and all future browsers should support it. Firefox 3 already supports document.activeElement. I've read that Opera supports it, but haven't tried. Safari does not, but the latest nightlies support it as well. Of course IE6 and IE7 support it perfectly well - IE invented it after all. So, of the big browsers, only Firefox 2 and Safari are problematic.

Since my code was not super critical, I've decided to skip support for just this bit for Firefox 2 and Safari. In any case, I'm hoping (against hope?) that both these browsers have a faster upgrade cycle than others, so they'll be outdated pretty soon.

Just in case you were thinking that the focused element can easily be 'discovered' by using the onblur and onfocus events, think again. Firstly, according to the specs, the focus and blur events don't bubble, so you can't use event delegation to capture all focus/blur events on the document. In any case, if you could use event delegation, putting these event handlers in an external script would mean that the script will kick in after a little delay - either after the script has loaded if the script tag is placed at the bottom, or after the page load happens if you are waiting for the DOM to be ready before you can use it, which in my case wasn't acceptable. The only other solution is to have a script include or a inline script tag that declares a function before the DOM is loaded, and then have inline onblur and onfocus event handlers DOM Level 0 style. That's just plain ugly. None of these solutions are either workable or graceful.


Unknown said...

Hey, thanks for the hint! Helped me to solve weird IE focus issue.

Unknown said...

focus and blur capture, so you could get somewhere with that

Erich said...

I am so grateful to have found this post. It is so well-explained.