2009-12-15 14 views
24

Usiamo ajaxError globale di jQuery() gestore per avvisare l'utente di eventuali guasti AJAX:jQuery ajaxError() incendi gestore se l'utente lascia pagina prima pagina finisce di caricare

$(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"); } } 
    }); 
}); 

Purtroppo, questo gestore errori globale spara anche se l'utente lascia la pagina prima che finisca il caricamento. Ecco i passaggi per riprodurre l'errore:

  1. Visite dell'utente Pagina A, che include elementi caricati tramite AJAX.
  2. Elementi AJAX nella pagina A caricamento in corso.
  3. L'utente fa clic sul collegamento per visitare la pagina B prima degli Gli elementi AJAX nella pagina A hanno terminato il caricamento.
  4. la finestra di dialogo di errore appare brevemente prima che il browser reindirizza alla pagina B.

Qualsiasi idea di come possiamo ottenere ajaxError() non innescare quando l'errore è direttamente causato da l'utente che visita una nuova pagina?

UPDATE: Ecco il mio codice ora, dopo che incorpora i suggerimenti nei commenti:

// 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!"; 
    } 
}; 

risposta

15

Ebbene sì, se l'utente passa a un'altra pagina, il XHR interrompe, che è, in effetti, un successo comunicazione. Una soluzione potrebbe essere quella di registrare un ascoltatore per l'evento onbeforeunload e di smistare lo ajaxError, dicendo sostanzialmente: l'utente sta per lasciare la pagina, quindi non desidero essere informato degli errori ajax che potrebbero verificarsi.

Alcuni siti, tuttavia, come GMail, fanno il contrario: se si tenta di allontanarsi dalla pagina mentre sono ancora in attesa alcune richieste Ajax, viene visualizzato un messaggio che informa che alcuni processi sono ancora in esecuzione in esecuzione, e consente all'utente di decidere se rimanere sul sito fino al completamento della richiesta, o di andare avanti e andare via.

+2

L'approccio GMail è di gran lunga migliore! – TheVillageIdiot

+2

beh sì, se devi avere un approccio generale generale, suppongo che sia quello che preferirei anch'io. anche se mi piacerebbe molto di più se un flag fosse passato alla funzione che effettua la chiamata ajax, determinando se la richiesta corrente era critica o meno. Ad esempio, se la richiesta è solo una sessione keep-alive, o il controllo di nuovi messaggi, o qualcosa del genere, si potrebbe desiderare di lasciarlo in silenzio. –

+0

David, grazie per il suggerimento. Non ho ancora testato quali browser supportino onbeforeunload, ma finora funziona bene su FF 3.5. Ho anche aggiunto un ritardo di 3 secondi alla finestra di dialogo di errore (un suggerimento da un commento precedente che sembra essere cancellato ora.) – richardkmiller

10

In base alla risposta di David Hedlund sopra ecco il codice che funziona per me:

//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'); 
}); 

ho avuto la 'ajaxError' spec dalla sezione commenti di jquery ajaxError documentation. Ho dovuto legare beforeunload a $(window) per supportare chrome (IE funzionava bene con il documento). .ajaxError non ha sparato quando ero impegnato a $(window) quindi questo è il motivo per cui ho questa soluzione finestra/documento.

Problemi correlati