Reputation: 4792
I am having some trouble with jquery's live and die methods.
//bind above function to clicking a
$('a').live('click', functionThatWaitsFiveSeconds)
I need to attach an event handler to clicking a link - and I want to unbind the handler while the function is running to prevent the function running over and over before it is complete (function is performing a ajax request then handling the response.
I can do all of the above just fine.
However, because the above handler is attached to a (a) tag I need to return false (to prevent the link from being followed). To do this I need to bind a different function to handle clicks and return false.
I need to know how to unbind my complicated function - while keeping my simple (return false) bound at all times.
The above fiddle should work, but after unbinding the event handler, it doesn't bind again? I've tried a few combinations of namespacing etc but cannot get this together.
Upvotes: 2
Views: 3359
Reputation: 20371
If you don't mind this approach (using a marker class) then this might be what you're looking for. No messy binding and unbinding of events - while trying to figure out a way to answer you question, I found it to be quite a bother to track everything that was bound/unbound on the page and I reached a stage once where I had multiple loaders appear for a single click.
$(document).ready(function(){
function functionThatWaitsFiveSeconds(el, e){
//stop default link click events
e.preventDefault();
e.stopPropagation();
if($(el).hasClass('loadingMarkerClass')) {
return false; //we're currently processing this element already
}
$(el).addClass('loadingMarkerClass'); //add a dummy, marker class to indicate we're showing a loader for this element
var loader = $('<div class="loader">Loading: ' + $(el).html() + '</div>');
$('#content').append(loader);
loader.animate({'width': '500'}, 5000, function(){
loader.remove();
$(el).removeClass('loadingMarkerClass');
});
}
//bind above function to clicking a
$('a').live('click', function(e){functionThatWaitsFiveSeconds(this, e)});
});
Upvotes: 1
Reputation: 40863
Update got it working
function denyRest() {
$("body").append("<h1>return false</h1>");
return false;
}
function functionThatWaitsFiveSeconds() {
$('a').die('click.thing', functionThatWaitsFiveSeconds);
var loader = $('<div class="loader">doing some stuff</div>');
$('#content').append(loader);
loader.animate({
'width': '500'
}, 5000, function() {
loader.remove();
$('a').die('click.otherthing', denyRest).live('click.thing', functionThatWaitsFiveSeconds).live('click.otherthing', denyRest);
});
}
$('a').live('click.thing', functionThatWaitsFiveSeconds);
$('a').live('click.otherthing', denyRest);
Updated fiddle.
I believe The issue was this.
Upvotes: 2
Reputation: 3384
Actually the easiest way to achieve this will be to remove the href tag on the anchor link.
So your code becomes
$(document).ready(function(){
function functionThatWaitsFiveSeconds(){
// $('a').die('click', functionThatWaitsFiveSeconds);
var loader = $('<div class="loader">doing some stuff</div>');
$(this).attr("href","#");
$('#content').append(loader)
loader.animate({'width': '500'}, 5000, function(){
loader.remove();
//now rebind click handler
// $('a').live('click', functionThatWaitsFiveSeconds)
})
}
//bind above function to clicking a
$('a').live('click', functionThatWaitsFiveSeconds)
//need to return false at all times to prevent folowing link
$('a').live('click',function(){
return false;
})
})
Upvotes: 0