2009-12-15 8 views
24

Wir verwenden jQuery globalen ajaxError() -Prozedur die Nutzer über AJAX Ausfälle aufmerksam zu machen:jQuery ajaxError() -Prozedur feuert, wenn der Benutzer verläßt Seite vor Seite fertig geladen

$(document).ajaxError(function() { 
    $("There was a network or server error. Please try again later.").dialog({ 
     title: "Error", 
     modal: true, 
     resizable: false, 
     buttons: { 'Ok': function() { (this).dialog("close"); } } 
    }); 
}); 

Leider ist diese globale Fehlerbehandlung auch ausgelöst, wenn Der Benutzer verlässt die Seite, bevor das Laden beendet ist. Hier sind die Schritte, um den Fehler zu reproduzieren:

  1. Benutzer besucht Seite A, die Elemente enthält, die über AJAX laden.
  2. AJAX-Elemente auf Seite A beginnen zu laden.
  3. Benutzer klickt auf den Link, um die Seite zu besuchen B vor AJAX-Elemente auf Seite A sind fertig geladen.
  4. Das Dialogfeld Fehler erscheint kurz bevor der Browser

Jede Idee zu Seite B. umleitet, wie wir ajaxError bekommen können() nicht auslösen, wenn der Fehler direkt durch den Benutzer verursacht wird, eine neue Seite zu besuchen?

UPDATE: Hier ist mein Code jetzt, nachdem die Vorschläge in den Kommentaren mit eingebauten

// I added a 3 second delay to our error dialog, enough time 
// for the user to leave for a new page: 
$(document).ajaxError(function() { 
    setTimeout(my_error_handler, 3000); 
}); 

// Warn user before leaving page if AJAX is still loading. 
// Not sure I'll keep this: 
$(document).ajaxStart(function() { 
    ajaxing = true; 
}); 

$(document).ajaxStop(function() { 
    ajaxing = false; 
}); 

window.onbeforeunload = function() { 
    if (typeof(ajaxing) != 'undefined' && ajaxing) { 
     return "Page elements are still loading!"; 
    } 
}; 

Antwort

15

Nun ja, wenn der Benutzer zu einer anderen Seite navigiert, wird die xhr abbrechen, die wirksam ist, ein erfolglose Kommunikation. Eine Lösung wäre, einen Listener für das Ereignis onbeforeunload zu registrieren und ajaxError dort zu lösen, im Grunde gesagt: Der Benutzer ist dabei, die Seite zu verlassen, so dass ich nicht über die Ajax-Fehler informiert werden möchte, die folgen könnten.

Einige Seiten, wie GMail, gehen jedoch anders herum: Wenn Sie versuchen, sich von der Seite zu entfernen, während noch einige Ajax-Anfragen ausstehen, erhalten Sie eine Meldung, dass Sie noch einige Prozesse haben läuft und lässt den Benutzer entscheiden, ob er auf der Website bleiben soll, bis die Anfrage beendet ist, oder um fortzufahren und fortzufahren.

+2

GMail Ansatz ist viel besser! – TheVillageIdiot

+2

Nun, ja, wenn Sie einen allgemeinen Ansatz haben müssen, nehme ich an, dass ich das auch bevorzuge. obwohl ich es viel lieber hätte, wenn ein Flag an die Funktion übergeben wurde, die den Ajax-Aufruf durchführt, um zu bestimmen, ob die aktuelle Anfrage kritisch war oder nicht. d. h., wenn die Anfrage nur eine Session-Keep-Alive-Sitzung oder eine Überprüfung auf neue Nachrichten oder etwas anderes ist, möchten Sie dies möglicherweise stillschweigend abbrechen lassen. –

+0

David, danke für den Vorschlag. Ich habe noch nicht getestet, welche Browser onbeforeunload unterstützen, aber es funktioniert bisher gut auf FF 3.5. Ich fügte dem Fehlerdialog auch eine Verzögerung von 3 Sekunden hinzu (ein Vorschlag aus einem früheren Kommentar, der jetzt anscheinend gelöscht wird.) – richardkmiller

10

Basierend auf David Hedlund Antwort oben hier ist der Code, der für mich funktioniert:

//enable global ajax error handling 
$(document).ajaxError(function (event, request, settings) { 
    //your error handling code here 
}); 

//user leaving page so ignore any unfinished ajax loads 
$(window).bind('beforeunload', function() { 
    $(document).unbind('ajaxError'); 
}); 

Ich habe die 'ajaxError' spec aus den Kommentaren von jquery ajaxError documentation. Ich musste beforeunload an $(window) binden, um Chrom zu stützen (IE arbeitete gut mit Dokument). .ajaxError hat nicht ausgelöst, als ich an $(window) gebunden war, deshalb habe ich diese Fenster-/Dokumentenlösung.