2012-03-13 22 views
9

estoy usando la siguiente maqueta para mostrar mi carga spinner mientras se hace peticiones AJAX en mi código jQuery:Retrasar la ruleta de carga mientras se hace peticiones Ajax en jQuery

jQuery.ajaxSetup({ 
beforeSend: function() { 
    $('#loader').show() 
}, 
complete: function(){ 
    $('#loader').hide() 
}, 
success: function() { 
    $('#loader').hide() 
} 
}); 

Este código funciona perfectamente bien para mí!

Sólo hay un problema:

Algunas solicitudes son sólo muy simple y rápido, por lo que el spinner carga se acaba de mostrar un par de millisecs. Eso por supuesto no es muy bonito.

Así que traté de usar setTimeout() para mostrar la aguja de carga ligeramente retrasada. Quiero que aparezca solo si las solicitudes AJAX toman al menos, digamos 100ms, pero no funcionó.

Necesito un código para retrasar la carga de la ruleta como expliqué anteriormente, por lo que SOLO aparece al hacer solicitudes AJAX "más largas".

+0

Cuando dice "pero no funcionó", ¿qué no funcionó? ¿Puedes mostrarnos el código que probaste? – jessegavin

+1

Además ... vaya fácil en el '!' Y el ':)' y el 'thx'. Me duelen los ojos. – jessegavin

Respuesta

0

La solución común que he visto es mantener la pulsación durante uno o dos segundos, incluso si la solicitud finaliza más rápido que eso. Algo así como:

var loaded = false; 
var throbbed = false; 

function checkComplete(){ 
    if(loaded && throbbed){ 
     $("#loader").hide(); 
    } 
} 

function requestComplete(){ 
    loaded = true; 
    checkComplete(); 
} 

jQuery.ajaxSetup({ 
beforeSend: function() { 
    $('#loader').show(); 
    setTimeout(function(){ 
     throbbed = true; 
     checkComplete(); 
    }, 500); 

}, 
complete: requestComplete, 
success: requestComplete 
}); 

Obviamente esto tiene un compromiso de hacer las cosas más lentas a expensas de mirar bastante, por lo que es el caso que dependen de si desea o no tomar ese golpe. Si es algo que se usa todo el tiempo, es mejor que aceptes lo feo. Si es algo que ocurre de vez en cuando, los usuarios no notarán 500 mil extra.

+0

no es lo que estaba buscando lo siento! ;) –

10

Éste es cómo ha solucionado la funcionalidad mencionada

var loading; 
    $("#loader").hide(); 
    jQuery.ajaxSetup({ 
     beforeSend: function() { 
      loading= setTimeout("$('#loader').show()", 300); 
     }, 
     complete: function(){ 
      clearTimeout(loading); 
      $("#loader").hide(); 
     }, 
     success: function() { 
      alert("done"); 
     } 
    }); 
+0

Esto presentará el mismo problema si la solicitud tarda 301 ms en completarse. Excepto peor, ya que ahora el usuario tiene que esperar un tiempo sin que aparentemente ocurra nada antes de que se muestre. –

+0

Supongo que un poco de preferencia. Si no sabe cuánto tiempo tomará su solicitud, creo que es más seguro decir: aguantar mostrando el cargador hasta que la solicitud caiga por encima de un umbral de carga rápida – r0m4n

+0

¡No funciona al 100%! :( El problema ahora es que el spinner de carga también se muestra al cargar la página la primera vez y no desaparece después. Intenté usar $ ('# loader'). Hide() @ document.ready pero todavía no ¡desaparece después de cargar la página correctamente! –

0

Esto debería funcionar:

var timeout; 

jQuery.ajaxSetup({ 
beforeSend: function() { 
    timeout = window.setTimeout(function() { 
     timeout = null; 
     $('#loader').show(); 
    }, 100); 
}, 
complete: function(){ 
    if (timeout) { 
     window.clearTimeout(timeout); 
     timeout = null; 
    } 
    $('#loader').hide() 
}, 
success: function() { 
    // No need to do anything here since complete always will be called 
} 
}); 

Ahora tiene que mejorar esta un poco si estás disparando varias pedido al mismo tiempo, pero espero que entiendas la imagen.

+0

¡No funciona al 100%! :( El problema ahora es que el girador de carga también se muestra al cargar la página la primera vez y no desaparece después. He intentado usar $ ('# loader'). Hide() @ document.ready pero aún no desaparece después de cargar la página con éxito! –

0

Responda ahora porque me encuentro con el mismo problema y estas respuestas me dan parte de la solución. Para evitar iniciar spinner después de que se complete la solicitud de ajax porque el tiempo de espera es más amplio que el script de ejecución, necesita una marca de verificación arriba/abajo, es muy simple y me resulta útil.

var m = $('.modal-ajax'); 
var run = false; // global scope is necessary 
m.hide(); // if isn't hidden in css 

jQuery.ajaxSetup({ 
    beforeSend: function() { 
     run = true; // up flag   
     d = setTimeout(function(){ 
      if(run) // is ajax executing now? 
       m.show(); 
     },100); // is trigged only for NO fast response 
    }, 
    complete: function(){ 
     m.hide(); 
     run = false; // down flag     
    }, 
    success: function() {    
    // do stuff 
    } 
}); 
3

Esta es una vieja pregunta pero he encontrado un enfoque mucho más agradable y elegante. jQuery expone una variable $.active que es el número de solicitudes ajax actualmente activas. El valor de esto aumenta antes de ajaxSend y disminuye después de ajaxComplete.

Con esto en mente, todo lo que necesitamos hacer es mostrar la ruleta cuando ajaxSend se dispara y $.active == '1' y ocultar la ruleta cuando se dispara y ajaxComplete$.active == '1'. Aquí está mi código que actualmente funciona perfectamente.

$(document).ajaxSend(function(event, request, settings) { 
    $.active == '1' ? $('#spinner').show() : ''; 
}); 

$(document).ajaxComplete(function(event, request, settings) { 
    $.active == '1' ? $('#spinner').hide() : ''; 
}); 

Espero que esto ayude a alguien.

Cuestiones relacionadas