I'm trying to add a $('body').live('click')
listener after the user clicks on a div. The purpose is creating a custom dropdown box that the user can open and eventually close by clicking anywhere on the page.
But when I add .live()
or .bind()
function inside a .click()
function, the live()
function is triggered for some reason:
$('#myDiv').click(function(){
$('#myDiv .child').show().addClass('showing');
$('body').live('click', function(){
$('#myDiv .child').hide();
$('body').die();
})
})
#myDiv
is shown but immediately hides, evidenced by the lingering .showing
class.
Am I using live()
wrong? How do I avoid this recursion?
return false
will stop event propagation:
$('#myDiv').click(function(){
$('#myDiv .child').show().addClass('showing');
$('body').live('click', function(){
$('#myDiv .child').hide();
$('body').die();
});
return false;
})
false
isn't exactly the same e.stopPropagation()
. Returning false causes jQuery to execute both e.stopPropagation()
and e.preventDefault()
. Maybe doesn't make a different to you in this case, but you should understand that it isn't exactly the same. As far as the event being passed to the event handler, it is always passed to an event handler whether you declare the argument or not - it's always there - jfriend00 2012-04-05 03:03
.one()
. If you use that instead of .live()
, then you don't need the .die()
line - jfriend00 2012-04-05 03:10
Use second body click binding without live (also you don't need it, because it always on page) and use timeout:
$('#myDiv').on('click',function(){
$('#myDiv .child').show().addClass('showing');
setTimeout(function(){
$('body').on('click', function(){
$('#myDiv .child').hide();
$('body').off('click');
});
},0);
});
live()
because I don't want $('body')
to always accept click events - podcastfan88 2012-04-05 02:49
Maybe it should work, maybe it shouldn't. But it doesn't. I'd recommend setting up all your event handlers at the beginning, and just have a global variable (e.g.) that tracks whether or not the second event handler should actually respond or not.
You probably have to stop propagation of the current event to keep it from bubbling up to the body where your new event handler will see it. Further, you can use .one()
for a one time event handler:
$('#myDiv').on('click',function(e){
$('#myDiv .child').show().addClass('showing');
e.stopPropagation();
$(document.body).one('click', function() {
$('#myDiv .child').hide();
});
})