I\'d like to cancel a .load() operation, when the load() does not return in 5 seconds. If it\'s so I show an error message like \'sorry, no picture loaded\'.
What I
You could simply set a timeout before loading the image as well as testing for a load error.
function LoadImage(yourImage) {
var imageTimer = setTimeout(function () {
//image could not be loaded:
alert('image load timed out');
}, 10000); //10 seconds
$(yourImage).load(function (response, status, xhr) {
if (imageTimer) {
if (status == 'error') {
//image could not be loaded:
alert('failed to load image');
} else {
//image was loaded:
clearTimeout(imageTimer);
//display your image...
}
}
});
}
$('#myImage').load(function(){...})
is not a function call to load the image, it is actually shorthand to bind a callback to the onload event.
Therefore, adding a timeout
parameter to the .load() method as suggested in other answers will have no effect.
It think your two options are:
Continue on the path you are
following and do something like
$('#myImage').attr('src', '');
to
cancel the image load after it times
out, or
Find some way to use $.ajax( { ... , timeout: 5000, ...} );
to load
the image instead of letting the
browser do it automatically via the
<img src="...">
attribute.
I don't think you can get there from here - as @Pointy mentioned, you need to need to get to the XmlHttpRequest object so you can access the .abort()
method on it. For that, you need the .ajax()
jQuery API which returns the object to you.
Barring the ability to abort the request, another method to consider is to add knowledge of the timeout into the callback function. You could do this two ways - first:
var hasImage = false;
$('#errorMessage')
.idle(5000, function() {
if(!hasImage) {
// 1. cancel .load()
// 2. show error message
// 3. Add an aborted flag onto the element(s)
$('#myImage').data("aborted", true);
}
});
And your callback:
$('#myImage')
.attr('src', '/url/anypath/image.png')
.load(function(){
if($(this).data("aborted")){
$(this).removeData("aborted");
return;
}
hasImage = true;
// do something...
});
Or you could bypass the idle for this particular functionality:
$('#myImage')
.attr('src', '/url/anypath/image.png')
.data("start", (new Date()).getTime())
.load(function(){
var start = $(this).data("start");
$(this).removeData("start");
if(((new Date()).getTime() - start) > 5000)
return;
hasImage = true;
// do something...
});
Neither approach is ideal, but I don't think you can directly cancel load as of jQuery 1.4 - might be a nice feature request to the jQuery team, though.
If you want any custom handling such as this, you simply can't use the jQuery.load() function. You'll have to upgrade to jQuery.ajax(), which I recommend anyway since you can do so much more with it, especially if you need any kind of error handling, it will be necessary.
Use the beforeSend option for jQuery.ajax and capture the xhr. Then you can create callback which can cancel the xhr after your timeout, and the callbacks as necessary.
This code is not tested, but should get you started.
var enableCallbacks = true;
var timeout = null;
jQuery.ajax({
....
beforeSend: function(xhr) {
timeout = setTimeout(function() {
xhr.abort();
enableCallbacks = false;
// Handle the timeout
...
}, 5000);
},
error: function(xhr, textStatus, errorThrown) {
clearTimeout(timeout);
if (!enableCallbacks) return;
// Handle other (non-timeout) errors
},
success: function(data, textStatus) {
clearTimeout(timeout);
if (!enableCallbacks) return;
// Handle the result
...
}
});
Your rephrased secondary question:
How do I cancel pending callback functions, created using the .load() method?
You can cancel all jquery callbacks, by using this 'nuclear' option:
$('#myImage').unbind('load');
I think the simplest thing to do would be to use $.ajax
directly. That way you can start a timeout, and from the timeout set a flag that the handler on the ajax call can check. The timeout can also show a message or whatever.