Wie ein jquery.load () abbrechen?
-
26-09-2019 - |
Frage
Ich möchte eine .load () Vorgang abzubrechen, wenn die Last () kehrt nicht in 5 Sekunden. Wenn es so dass ich eine Fehlermeldung wie zeigen ‚sorry, geladen kein Bild‘.
Was ich habe, ist ...
... die Timeout-Behandlung:
jQuery.fn.idle = function(time, postFunction){
var i = $(this);
i.queue(function(){
setTimeout(function(){
i.dequeue();
postFunction();
}, time);
});
return $(this);
};
... Initialisierung der Fehlermeldung Timeout:
var hasImage = false;
$('#errorMessage')
.idle(5000, function() {
if(!hasImage) {
// 1. cancel .load()
// 2. show error message
}
});
... das Bild Laden:
$('#myImage')
.attr('src', '/url/anypath/image.png')
.load(function(){
hasImage = true;
// do something...
});
Das einzige, was ich nicht verstehen konnte heraus ist, wie die Lauflast () abbrechen (wenn es möglich ist).
Edit:
Eine andere Art und Weise: Wie kann ich die .load () -Methode verhindern, dass es die Callback-Funktion aufrufen, wenn es zurückkehrt
Lösung
Wenn Sie diese beliebige benutzerdefinierte Umgang mit solchen möchten, können Sie einfach nicht die jQuery.load () Funktion verwenden. Sie werden zu jQuery.ajax aktualisieren haben (), die ich sowieso empfehlen, da man damit so viel mehr tun, vor allem, wenn Sie jede Art von Fehlerbehandlung benötigen, wird es notwendig sein.
Verwenden Sie die beforeSend Option für jQuery.ajax und die xhr erfassen. Dann können Sie Rückruf erstellen, die die xhr nach dem Timeout zurücktreten können, und die Rückrufe wie nötig.
Dieser Code ist nicht getestet, aber sollten Sie begonnen erhalten.
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
...
}
});
Andere Tipps
Ihre umformuliert sekundäre Frage:
Wie kann ich cancel anstehende Callback-Funktionen, erstellt die .load () Methode verwendet?
Sie können alle jquery Rückrufe abbrechen, indem Sie diese "nukleare Option:
$('#myImage').unbind('load');
Ich denke, die einfachste Sache direkt zu verwenden $.ajax
zu tun wäre. Auf diese Weise können Sie einen Timeout starten und aus dem Timeout einen Flag, dass der Handler auf dem Ajax-Aufruf überprüfen. Das Timeout kann auch eine Meldung oder was auch immer.
Wenn Sie diesen Code laden, nachdem JQuery geladen wurde Sie in der Lage sein wird, .load () mit einem Timeout-Parameter zu nennen.
jQuery.fn.load = function( url, params, callback, timeout ) {
if ( typeof url !== "string" ) {
return _load.call( this, url );
// Don't do a request if no elements are being requested
} else if ( !this.length ) {
return this;
}
var off = url.indexOf(" ");
if ( off >= 0 ) {
var selector = url.slice(off, url.length);
url = url.slice(0, off);
}
// Default to a GET request
var type = "GET";
// If the second parameter was provided
if ( params ) {
// If it's a function
if ( jQuery.isFunction( params ) ) {
if( callback && typeof callback === "number"){
timeout = callback;
callback = params;
params = null;
}else{
// We assume that it's the callback
callback = params;
params = null;
timeout = 0;
}
// Otherwise, build a param string
} else if( typeof params === "number"){
timeout = params;
callback = null;
params = null;
}else if ( typeof params === "object" ) {
params = jQuery.param( params, jQuery.ajaxSettings.traditional );
type = "POST";
if( callback && typeof callback === "number"){
timeout = callback;
callback = null;
}else if(! timeout){
timeout = 0;
}
}
}
var self = this;
// Request the remote document
jQuery.ajax({
url: url,
type: type,
dataType: "html",
data: params,
timeout: timeout,
complete: function( res, status ) {
// If successful, inject the HTML into all the matched elements
if ( status === "success" || status === "notmodified" ) {
// See if a selector was specified
self.html( selector ?
// Create a dummy div to hold the results
jQuery("<div />")
// inject the contents of the document in, removing the scripts
// to avoid any 'Permission Denied' errors in IE
.append(res.responseText.replace(rscript, ""))
// Locate the specified elements
.find(selector) :
// If not, just inject the full result
res.responseText );
}
if ( callback ) {
self.each( callback, [res.responseText, status, res] );
}
}
});
return this;
};
Nicht sicher, ob Sie beim Überschreiben keine „Standard“ JQuery Funktionen interessiert sind, aber dies würde erlauben Sie verwenden .load (), um die Art und Weise Sie beschrieben.
Ich glaube nicht, dass Sie von hier aus dorthin gelangen können - wie @Pointy erwähnt, müssen Sie Notwendigkeit, das XMLHttpRequest-Objekt zu erhalten, so dass Sie die .abort()
Methode auf sie zugreifen können. Dafür müssen Sie die .ajax()
jQuery API, die das Objekt zu Ihnen zurück.
die Fähigkeit Barring die Anforderung abzubrechen, eine andere Methode zu prüfen, ist die Kenntnis der Zeitüberschreitung in die Callback-Funktion hinzuzufügen. Sie könnten diese zwei Möglichkeiten - erstens:
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);
}
});
Und Ihr Rückruf:
$('#myImage')
.attr('src', '/url/anypath/image.png')
.load(function(){
if($(this).data("aborted")){
$(this).removeData("aborted");
return;
}
hasImage = true;
// do something...
});
Oder Sie könnten den Leerlauf für diese besondere Funktionalität umgehen:
$('#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...
});
Weder Ansatz ist ideal, aber ich glaube nicht, dass Sie direkt Last wie von jQuery 1.4 abbrechen -. Könnte eine nettes Feature Anfrage an das jQuery-Team, obwohl
$('#myImage').load(function(){...})
ist kein Funktionsaufruf um das Bild zu laden, es ist eigentlich eine Abkürzung zu binden, um einen Rückruf an das onload
Ereignis .
Daher Hinzufügen eines timeout
Parameter an die .load()
Methode wie vorgeschlagen in anderen Antworten werden keine Auswirkungen haben.
Es denken, dass Ihre beiden Optionen sind:
-
Weiter auf dem Weg Sie sind Folgende und etwas tun, wie
$('#myImage').attr('src', '');
zu brechen Sie die Bild Last, nachdem es mal out oder -
Einen Weg finden, um die Verwendung
$.ajax( { ... , timeout: 5000, ...} );
zu Last das Bild stattdessen die der Vermietung Browser tun es automatisch über die<img src="...">
Attribut.
Sie könnten einfach ein Timeout einstellen, bevor das Bild als auch die Prüfung für einen Ladefehler zu laden.
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...
}
}
});
}