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

War es hilfreich?

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:

  1. 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

  2. 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...
            }

        }
    });

}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top