13

I'm using the following code to animate a block. In my code, div_animate() essentially hides a <div> with the specified selector if it is currently visible.

$(document).click(function(event){
    div_animate("#container");
});

I need to determine whether the user clicked on a child of #container and if so, return false; -- as far as I can tell, the code for this would look something like this:

$(document).click(function(event){
    if ( /* the event's target has a parent of #container */ ) {
        return false;
    } else {
        div_animate("#container");
    }
});

Any thoughts?

Mandeep Jain
  • 2,304
  • 4
  • 22
  • 38
WNRosenberg
  • 1,862
  • 5
  • 22
  • 31
  • Is this the same issue as [your previous question](http://stackoverflow.com/questions/4430277/jquery-animate-when-div-loses-focus) where I gave you [this link](http://stackoverflow.com/questions/714471/jquery-hide-element-when-clicked-anywhere-on-the-page)? – user113716 Dec 13 '10 at 18:22
  • @patrick This is not the same as my previous question, but it is related -- this issue arose when I added the solution from the previous question. While your link was similar to my original question, I did not find it useful. – WNRosenberg Dec 13 '10 at 23:09

2 Answers2

28

The simplest thing would be:

if ($(event.target).is('#container *, #container')) // edited - thanks @gnarf
  // is a child
else
  // is not a child

There are different choices you could make for detecting whether it's a child of the target (or non-target) container; that's just one. An alternative:

if ($(event.target).closest('#container').length)
Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 1
    That wouldn't find `#container` on its own though... Maybe `$(event.target).closest('#container').length` or `.is('#container, #container *')` – gnarf Dec 13 '10 at 18:16
  • 1
    @gnarf ah yes you're right - I had added the "closest" alternative too already but I'll fix the first one. – Pointy Dec 13 '10 at 18:18
  • @Jazzerus make sure you note the slight edit I made, based on gnarf's comment, and also note Nick's answer(s) – Pointy Dec 13 '10 at 18:20
  • this will not work properly when `$(anotherselector).trigger(event)` is activated inside the related selector. Example: `$(something).click(function(){ $(anotherselector).trigger(event); });` when this is done `$(document).click(function(e){ if(e.target).is(something) { } });` will always read `anotherselector` as the target of the event, instead of `something`. – Ari May 17 '16 at 16:58
  • @KeepMove yes, that's true. – Pointy May 17 '16 at 17:00
9

You can prevent the action if the click originated on or in #container, like this:

$(document).click(function(event){
    var c = $("#container")[0];
    if (event.target == c || $.contains(c, event.target)) {
        return false;
    } else {
        div_animate("#container");
    }
});

The first check is if it came from #container itself, the second is if it came from a child, that #container $.contains(). A completely alternative, simpler way is to just prevent the bubble up to document when clicking on #container, like this:

$("#container").click(function(e) {
  e.stopPropagation();
});
$(document).click(function() {
  div_animate("#container");
});
Nick Craver
  • 623,446
  • 136
  • 1,297
  • 1,155
  • Here is my golden opportunity to chastise you for not caching that "#container" lookup, but I bet you'll have edited it by the time I finish typing this comment :-) – Pointy Dec 13 '10 at 18:17
  • No I meant cached in a closure around the handler function or something, though mostly I was just kidding. – Pointy Dec 13 '10 at 18:19
  • @Pointy - ah yeah you could, though you're *assuming* it's not changing or moving in that case ;) – Nick Craver Dec 13 '10 at 18:20