views:

65

answers:

4

I have a div, I want to set it so that when I click on something else, it would hide the div.

So I did

$('body').click(function(){
    if(loginOpened)
    {
        $('#loginWindow').animate({
            'width':'0px',
            'height':'0px'
        },"fast");
    }
    loginOpened=false;
});

However, even when I click in the div itself the event is fired, is there anyway to prevent this?

+3  A: 

You can stop it using

e.stopPropagation(); if there is a click event bound to the <div /> tag.

See event.stopPropagation()

Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.

Otherwise you can check the target of the event inside the body click. Check whether event.target is the same as your div.

See event.target

rahul
+2  A: 

Just check the event.target. If the element that triggered the event is your div do not execute the code.

$('body').click(function(evt){
    evt = evt || window.event
    if ($(evt.target) != $('#loginWindow')) {
      if(loginOpened)
      {
          $('#loginWindow').animate({
              'width':'0px',
              'height':'0px'
          },"fast");
      }
      loginOpened=false;
    }
});
John Hartsock
Can we compare `$(evt.target)` with `$('#loginWindow')`? Will the two objects be the same?
rahul
@rahul ..Yes they should be. but even if they are not you can comparre $(evt.target).attr('id') with "loginWindow" ... the id property should match.
John Hartsock
+1  A: 

Yes, but of course Microsoft and the rest of the world came to different conclusions about how to do it. This site gives a good clear rundown of what's needed: http://www.quirksmode.org/js/events_order.html .

I don't use jQuery but the jQuery way appears to be event.stopImmediatePropagation(); as seen in this question: http://stackoverflow.com/questions/652495/jquery-multiple-event-handlers-how-to-cancel .

bemace
A: 

A couple of changes from John's code:

$('body').click(function(ev){
    // jQuery means never having to say "window.event"!
    // Also, code's cleaner and faster if you don't branch, 
    // and choose simple breaks over more complex ones
    if(!loginOpened) return;
    // Lastly, compare using the DOM element; 
    // jQuery objects never compare as the "same"*
    if (ev.target == $('#loginWindow').get(0)) return;  
    $('#loginWindow').animate({
        'width':'0px',
        'height':'0px'
    },"fast");
    loginOpened=false;
});

If trapping it in the body event doesn't work for you, you can just add a simple event handler to the div:

$('#loginWindow').click(function (ev) { ev.stopPropagation(); });

I was going to say return false, but that would prevent other things from firing off the div. stopPropagation just keeps the event from bubbling outward.

I could be really picky, of course...

//Delegation via the document element permits you to bind the event before
// the DOM is complete; no flashes of unbehaviored content
$(document).delegate('body', 'click', function(ev){
    //You only have one instance of an id per page, right?
    if(!loginOpened || ev.target.id == 'loginWindow') return;
    //quotes and px?  not necessary.  This isn't json, and jQ's smart
    $('#loginWindow').animate({width:0,height:0},"fast");
    loginOpened=false;
});

* Don't believe me? Try:

jQuery('#notify-container') == jQuery('#notify-container') 

Then try

jQuery('#notify-container').get(0) == jQuery('#notify-container').get(0)
Fordi