vol7ron
vol7ron

Reputation: 42099

jQuery: Firefox focusout Event

I've got two input boxes in a div, I want to hide that div on the focusOut of the inputs, but only if both of them do not have focus.

This is a common Firefox problem (some call it adhering to standard), but the document body steals focus between.

HTML


<div id="baz">
   <input type="text" id="foo" name="foo" />
   <input type="text" id="bar" name="bar" />
</div>

jQuery


// jQuery Example
jQuery(":input").focusout(function(){
   // Don't do anything if one of the input boxes has focus
   if( jQuery(":input").is( jQuery(document.activeElement) ){ return; }

   // Hide the container if one of the inputs loose focus
   jQuery(this).parents("div").css("display","none");
}

Though this is a common bug, I forget how I solved it in the past. I think it had something to do with setting a timeout, or doing a screen refresh, before checking for the activeElement.


jsFiddle Example

jsFiddle Updated (FF4 Same Problem)

Upvotes: 1

Views: 3022

Answers (2)

vol7ron
vol7ron

Reputation: 42099

I think amit_g's solution was almost there. I vaguely remember that I've went about this in two ways:

  1. compare the inputs to the activeElement (the method showed above)
  2. setting/clearing a "focus" class on the element for the respective events

I think both methods required using setTimeout, since Firefox has a delayed trigger, which we need to force. While I've heard FF is adhering to standards here, I personally think that standard needs to be amended.


So in addition to adding the timed function call, it also needed to be cleared if the other "acceptable" element gained focus. The following is not production code but it does show it does serve as an example:

Example Solution

Example Solution (Even Better) - set $debug to false

Example Solution (Localized Blocks) - removed debugging clutter

Upvotes: 0

amit_g
amit_g

Reputation: 31250

Demo

jQuery(":input").focusout(function(){
    var elem = jQuery(this).parent("div");
    window.setTimeout(function(){
            // Don't do anything if one of the input boxes has focus
            if( jQuery(":input").is( jQuery(document.activeElement) )){ return; }

            // Hide the container if one of the inputs loose focus
            elem.hide();
    }, 0);
})

Demo

jQuery(document).ready(function () {
    var timeoutID;

    jQuery(":input").focus(function () {
        window.clearTimeout(timeoutID);
    }).focusout(function () {
        timeoutID = window.setTimeout(function () {
            jQuery("#baz").hide();
        }, 0);
    });
});

Upvotes: 7

Related Questions