14

I want to close a little pop-up box in page when user has clicked anywhere on the page other than box area. how to find it?

coure2011
  • 40,286
  • 83
  • 216
  • 349

4 Answers4

17
$(document.body).click(function(e){
   var $box = $('#little-pop-up-box-id');
   if(e.target.id !== 'little-pop-up-box-id' && !$.contains($box[0], e.target))
      $box.remove();
});

e.target is the DOM node which received the click event. I'm checking first if the ID of that element is not the one we are looking for.

The second check !$.contains($box[0], e.target) makes sure, that the DOM node of invocation is not within the element we want to hide.

Well, I guess it's plugin time! :

(function($){
   $.fn.outside = function(ename, cb){
      return this.each(function(){
         var $this = $(this),
              self = this;
         $(document.body).bind(ename, function tempo(e){
             if(e.target !== self && !$.contains(self, e.target)){
                cb.apply(self, [e]);
                if(!self.parentNode) $(document.body).unbind(ename, tempo);
             }
         });
      });
   };
}(jQuery));

synopsis

$('#container').outside('click', function(e){
    $(this).remove();
});

Example:

http://www.jsfiddle.net/qbDKN/30/

jAndy
  • 231,737
  • 57
  • 305
  • 359
  • This is a good solution - just two quick comments though. It would probably make sense to cache the $box var outside of the click handler to avoid re-querying (albeit a cheap query). And if you're using a 1.3.2+ version of jQuery, !$(e.target).closest('#little-pop-up-box-id').length would make a more concise conditional. /nitpicking – jmar777 Aug 09 '10 at 12:57
  • ACHHHH!! TEH CHAIN - IT'S BROKEN! (otherwise... sweetness, +1). Also... should the 'click' literal be replaced with the ename var? – jmar777 Aug 09 '10 at 13:19
  • @jmar777: right, fixed that :p. I also added an `.unbind()`.. Well I guess this can be optimized at several places. Maybe even a good idea to use `.delegate()`. Who the f**k needs Ben Alman? :) j/k – jAndy Aug 09 '10 at 13:23
  • @jAndy - good call on using "self" for the apply. Definitely stays more consistent with the other event registration methods. For the "outside" condition, perhaps (e.target !== self) would be better than checking the ID's, since that'll work when ID's aren't present. – jmar777 Aug 09 '10 at 13:40
  • @jmar777: nice one, changed that. – jAndy Aug 09 '10 at 13:44
  • @coure06: well, the code above works fine (see the example link). Can you provider your code? – jAndy Aug 09 '10 at 21:19
  • I dont get the line: if(!self.parentNode) $(document.body).unbind(ename, tempo); – Toskan Aug 14 '12 at 16:05
  • ah I get it -since you remove the element, you check whether you can unbind the event handler. Eventually you should parameterize that – Toskan Aug 14 '12 at 16:09
  • Works OK when remove: (function($){ .. }(jQuery)); and add into: $(document).ready(function() { – user956584 Sep 18 '12 at 11:57
4

@jAndy's solution is good, but I wanted to mention Ben Alman's "Outside Events" plugin as well. Here's a quick example using it:

$("#popup").bind("clickoutside", function(event){
  $(this).hide();
});
jmar777
  • 38,796
  • 11
  • 66
  • 64
1
$("html").click(function(){
//close popup
});
Alexander_F
  • 2,831
  • 3
  • 28
  • 61
0

Grab global click event, or setup transparent div 100%/100% under the pop-up box with such event.

Thinker
  • 14,234
  • 9
  • 40
  • 55