¿Cómo mostrar un indicador de "ocupado" con jQuery?

81

¿Cómo muestro un indicador de "ocupado" giratorio en un punto específico de una página web?

Quiero iniciar / detener el indicador cuando comienza / completa una solicitud Ajax.

¿Es realmente solo una cuestión de mostrar / ocultar un gif animado, o hay una solución más elegante?

Tony el pony
fuente

Respuestas:

94

Simplemente puede mostrar / ocultar un gif, pero también puede incrustarlo en ajaxSetup, por lo que se llama en cada solicitud de ajax.

$.ajaxSetup({
    beforeSend:function(){
        // show gif here, eg:
        $("#loading").show();
    },
    complete:function(){
        // hide gif here, eg:
        $("#loading").hide();
    }
});

Una nota es que si desea hacer una solicitud ajax específica sin tener el spinner de carga, puede hacerlo así:

$.ajax({
   global: false,
   // stuff
});

De esa manera, el $ .ajaxSetup anterior que hicimos no afectará la solicitud con global: false.

Más detalles disponibles en: http://api.jquery.com/jQuery.ajaxSetup

Rodrigo
fuente
2
+1 para ajaxSetup(). Preferiría que globalse dieran más explicaciones sobre la propiedad.
RabidFire
@RabidFire, en realidad no se necesita global aquí, es solo por $ .ajax
Rodrigo
@gov, el posicionamiento del gif depende del diseño, puede ocultar / mostrar el div donde está colocado, en lugar de modificar dom.
Rodrigo
1
Esto parecía prometedor pero no funcionó para mí, terminé probando una solución diferente que funcionó. stackoverflow.com/questions/7003707/…
Bob
Si tiene 2 XHR y el primero finaliza justo después de que comience el segundo, este código oculta el indicador de carga aunque el segundo XHR todavía se esté ejecutando.
Mark E. Haase
39

La documentación de jQuery recomienda hacer algo como lo siguiente:

$( document ).ajaxStart(function() {
  $( "#loading" ).show();
}).ajaxStop(function() {
  $( "#loading" ).hide();
});

¿Dónde #loadingestá el elemento con su indicador de ocupado?

Referencias:

  • http://api.jquery.com/ajaxStart/
  • http://api.jquery.com/ajaxStop/

  • Además, jQuery.ajaxSetupAPI recomienda explícitamente evitar jQuery.ajaxSetuppara estos:

    Nota: Las funciones de devolución de llamada globales deben establecerse con sus respectivos métodos-mundial Ajax controlador de eventos .ajaxStart(), .ajaxStop(), .ajaxComplete(), .ajaxError(), .ajaxSuccess(), .ajaxSend()-en lugar de en el optionsobjeto para $.ajaxSetup().

Sean W.
fuente
1
Estos parecen más útiles que antes. Enviar y completar, porque ajaxStart "... Registrará un controlador para que sea llamado cuando comience la primera solicitud Ajax" y ajaxStop "... Registrará un controlador para ser llamado cuando todas las solicitudes Ajax se hayan completado" - estos manejan mensajes asincrónicos concurrentes y no esconden el indicador "por favor espere" prematuramente.
gap
10

Tiendo a mostrar / ocultar una IMG como han dicho otros. Encontré un buen sitio web que genera "cargando gifs"

Enlace Lo acabo de poner dentro de ay lo oculto divpor defecto display: none;(css) luego, cuando llamas a la función, mostrar la imagen, una vez que esté completa, la oculto nuevamente.

Elliott
fuente
6

sí, en realidad es solo una cuestión de mostrar / ocultar un gif animado.

Chase Florell
fuente
2
Convenido. Mostrar / ocultar una imagen es fácil y todos los navegadores lo entienden. Hay un par de complementos de jquery rotar para imágenes, pero no funcionarán en todos los navegadores.
Mike Blandford
@mike, mi solución funciona bien para mi proyecto en todos los navegadores, ¿crees que es un buen enfoque?
kobe
4

Lo hice en mi proyecto,

hacer un div con URL de fondo como gif, que no es más que gif de animación

<div class="busyindicatorClass"> </div>

.busyindicatorClass
{
background-url///give animation here
}

en su llamada ajax, agregue esta clase al div y en ajax exitosamente elimine la clase.

hará el truco que se sienta.

avíseme si necesita algo más, puedo darle más detalles

en el éxito de ajax eliminar la clase

success: function(data) {
    remove class using jquery
  }
Kobe
fuente
4

Para extender un poco la solución de Rodrigo, para las solicitudes que se ejecutan con frecuencia, es posible que solo desee mostrar la imagen de carga si la solicitud toma más de un intervalo de tiempo mínimo; de lo contrario, la imagen aparecerá continuamente y desaparecerá rápidamente.

var loading = false;

$.ajaxSetup({
    beforeSend: function () {
        // Display loading icon if AJAX call takes >1 second
        loading = true;
        setTimeout(function () {
            if (loading) {
                // show loading image
            }
        }, 1000);            
    },
    complete: function () {
        loading = false;
        // hide loading image
    }
});
John M
fuente
3

Lo hice en mi proyecto:

Eventos globales en application.js:

$(document).bind("ajaxSend", function(){
   $("#loading").show();
 }).bind("ajaxComplete", function(){
   $("#loading").hide();
 });

"loading" es el elemento a mostrar y ocultar!

Referencias: http://api.jquery.com/Ajax_Events/

albert yu
fuente
3

Tuve que usar

HTML:
   <img id="loading" src="~/Images/spinner.gif" alt="Updating ..." style="display: none;" />

In script file:
  // invoked when sending ajax request
  $(document).ajaxSend(function () {
      $("#loading").show();
  });

  // invoked when sending ajax completed
  $(document).ajaxComplete(function () {
      $("#loading").hide();
  });
Ken Mc
fuente
2

Hilo antiguo, pero quería actualizar ya que trabajé en este problema hoy, no tenía jquery en mi proyecto, así que lo hice a la manera simple de JavaScript, también necesitaba bloquear el contenido en la pantalla, así que en mi xhtml

    <img id="loading" src="#{request.contextPath}/images/spinner.gif" style="display: none;"/>

en mi javascript

    document.getElementsByClassName('myclass').style.opacity = '0.7'
    document.getElementById('loading').style.display = "block";
Sandeepraj Tandon
fuente
¿A qué te refieres con "la vieja forma de JavaScript"? ¿Podría explicarnos más? ¿Quieres decir que usaste un XMLHttpRequest?
Brian Peterson