Reputation: 9282
I'm making some tests to try to learn a little bit more about deferreds. So, I made an ajax web navigation:
$('ul#nav a').on('click', function(e){
var hash = $(this).attr('href');
check(hash).fail(function(){
e.preventDefault();
});
});
function check(hash){
var deferred = $.Deferred();
if (!hash) {
hash = window.location.hash;
}
if (!hash) {
var url = window.location.pathname;
var file = url.substring(url.lastIndexOf('/')+1);
hash = file.replace(extension,'');
}
if (hash !== prev_url){
prev_url= hash;
loadPage(hash).done(
function(data){
var html = $(data);
var filtered= html.find('#content');
content.html(filtrado.html());
deferred.resolve();
}
).fail(function(){ // Url doesn't exist
content.html('<p>Page does not exist!</p>');
deferred.reject();
});
}
return deferred;
}
Everything seems to be working fine except the check.fail function has no access to the event object so I'm unable to prevent the page change and so, it fails.
Upvotes: 0
Views: 188
Reputation: 22395
The fail
callback closes over e
(it is a closure) so it definitely should have access (or do you get an error?).
The problem is likely that at the moment the fail
callback is executed (some time later as you are doing an Ajax request, which is asynchronous), the event handling is already completed. Calling e.preventDefault()
does not have any effect anymore.
You need to do e.preventDefault();
straight after the click and assume the page doesn't exist until the asynchronous Deferred events tell you otherwise.
$('ul#nav a').on('click', function(e){
e.preventDefault(); // Assume bad link until otherwise proven
var hash = $(this).attr('href');
check(hash).done(function(){
window.location.href = hash; // Good hash, let's go to that
});
});
Upvotes: 3