Yikes. Tricky. Yes, what's happening is:
mousedown
: old form element gets the blur
event. $(':focus').length == 0
.
mouseup
: new form element gets the focus
event. $newFormElement.is(':focus') == true
.
This is an improvement:
$('#tracker').focusout(function() //basically like $('#tracker, #tracker *').blur(), but "this" is always '#tracker'
{
if(!$(this).is('#tracker:hover')) //for some reason plain old :hover doesn't work, at least on the latest OS X Chrome
hideTracker();
});
But it's not perfect. It only really works if you use the mouse. If you use tab to move between fields (or some other possible mechanism) while your mouse is not hovering over #tracker
, it won't work.
Here's another attempt. It's a bit...hackier. The gist is that, instead of handling the blur
event, you handle the focus
event of the second thing that's focused. But! What if you click something that can't be focused? Blank space on your page? Then no focus
event is fired.
Okay. So the trick is: put a tabindex="0"
in your root <html>
tag. This means that there is always something that can be focused. So there's no way to focus on nothing (at least, I don't think so).
Then you can do this:
$('*').live('focus', function(e)
{
if(!$.contains($('#tracker')[0], this)) //if the new thing you focused on is not a descendant of #tracker
hideTracker();
e.stopPropagation();
});
Eh? So yeah, that's a certified hack. But it's a tough problem, and that's the best I can come up with at this hour.