¿Cómo puedo crear una animación “Espere, cargue …” usando jQuery?

Me gustaría colocar una animación de círculo giratorio “por favor espere, cargue” en mi sitio. ¿Cómo debo lograr esto usando jQuery?

Podrías hacer esto de diferentes maneras. Podría ser sutil como un pequeño estado en la página que dice “Cargando …”, o tan alto como un elemento completo encapsulando la página mientras se cargan los datos nuevos. El enfoque que estoy tomando a continuación le mostrará cómo lograr ambos métodos.

La puesta en marcha

Comencemos por obtener una buena animación de “carga” desde http://ajaxload.info. Voy a usar enter image description here

Vamos a crear un elemento que podamos mostrar / ocultar cada vez que hagamos una solicitud de Ajax:

  

El CSS

Siguiente vamos a darle un toque:

 /* Start by setting display:none to make this hidden. Then we position it in relation to the viewport window with position:fixed. Width, height, top and left speak for themselves. Background we set to 80% white with our animation centered, and no-repeating */ .modal { display: none; position: fixed; z-index: 1000; top: 0; left: 0; height: 100%; width: 100%; background: rgba( 255, 255, 255, .8 ) url('http://i.stack.imgur.com/FhHRx.gif') 50% 50% no-repeat; } /* When the body has the loading class, we turn the scrollbar off with overflow:hidden */ body.loading .modal { overflow: hidden; } /* Anytime the body has the loading class, our modal element will be visible */ body.loading .modal { display: block; } 

Y finalmente, el jQuery

Muy bien, a la jQuery. La siguiente parte es realmente muy simple:

 $body = $("body"); $(document).on({ ajaxStart: function() { $body.addClass("loading"); }, ajaxStop: function() { $body.removeClass("loading"); } }); 

¡Eso es! ajaxStart algunos eventos al elemento del cuerpo cada ajaxStart ajaxStop eventos ajaxStart o ajaxStop . Cuando comienza un evento ajax, agregamos la clase “cargando” al cuerpo. y cuando se hacen eventos, eliminamos la clase “cargando” del cuerpo.

Véalo en acción: http://jsfiddle.net/VpDUG/4952/

En cuanto a la imagen de carga real, consulte este sitio para ver un montón de opciones.

En cuanto a mostrar un DIV con esta imagen cuando comienza una solicitud, tiene algunas opciones:

A) Mostrar y ocultar manualmente la imagen:

 $('#form').submit(function() { $('#wait').show(); $.post('/whatever.php', function() { $('#wait').hide(); }); return false; }); 

B) Usa ajaxStart y ajaxComplete :

 $('#wait').ajaxStart(function() { $(this).show(); }).ajaxComplete(function() { $(this).hide(); }); 

Al usar esto, el elemento se mostrará / ocultará para cualquier solicitud. Podría ser bueno o malo, dependiendo de la necesidad.

C) Usar devoluciones de llamada individuales para una solicitud particular:

 $('#form').submit(function() { $.ajax({ url: '/whatever.php', beforeSend: function() { $('#wait').show(); }, complete: function() { $('#wait').hide(); } }); return false; }); 

Junto con lo que Jonathan y Samir sugirieron (¡ambas excelentes respuestas, por cierto!), JQuery tiene algunos eventos integrados que disparará cuando haga una solicitud de Ajax.

ajaxStart evento ajaxStart

Muestre un mensaje de carga cada vez que se inicie una solicitud AJAX (y ninguna ya está activa).

… y es hermano, el evento ajaxStop

Adjunte una función que se ejecutará cuando todas las solicitudes AJAX hayan finalizado. Este es un Evento Ajax.

Juntos, hacen una buena manera de mostrar un mensaje de progreso cuando cualquier actividad de Ajax está sucediendo en cualquier parte de la página.

HTML:

 

Please Wait

Guión:

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

Puedes tomar un GIF animado de un círculo giratorio de Ajaxload , pegarlo en algún lugar de la jerarquía de archivos de tu sitio web. Luego, solo necesita agregar un elemento HTML con el código correcto y eliminarlo cuando haya terminado. Esto es bastante simple:

 function showLoadingImage() { $('#yourParentElement').append('
Loading...
'); } function hideLoadingImage() { $('#loading-image').remove(); }

Entonces solo necesita usar estos métodos en su llamada AJAX:

 $.load( 'http://example.com/myurl', { 'random': 'data': 1: 2, 'dwarfs': 7}, function (responseText, textStatus, XMLHttpRequest) { hideLoadingImage(); } ); // this will be run immediately after the AJAX call has been made, // not when it completes. showLoadingImage(); 

Esto tiene algunas advertencias: en primer lugar, si tiene dos o más lugares donde se puede mostrar la imagen de carga, necesitará hacer un seguimiento de cuántas llamadas se ejecutan a la vez de alguna manera, y solo ocultarlas cuando estén todo listo. Esto se puede hacer usando un contador simple, que debería funcionar para casi todos los casos.

En segundo lugar, esto solo ocultará la imagen de carga en una llamada AJAX exitosa. Para manejar los estados de error, necesitará buscar $.ajax , que es más complejo que $.load , $.get y similares, pero también mucho más flexible.

La excelente solución de Jonathon se rompe en IE8 (la animación no se muestra en absoluto). Para solucionar esto, cambie el CSS a:

 .modal { display: none; position: fixed; z-index: 1000; top: 0; left: 0; height: 100%; width: 100%; background: rgba( 255, 255, 255, .8 ) url('http://i.stack.imgur.com/FhHRx.gif') 50% 50% no-repeat; opacity: 0.80; -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity = 80); filter: alpha(opacity = 80)}; 

jQuery proporciona ganchos de eventos para cuando las solicitudes AJAX comiencen y finalicen. Puede conectarlos para mostrar su cargador.

Por ejemplo, crea la siguiente div:

 
Loading

Configúrelo para display: none en sus hojas de estilo. Puedes darle el estilo que quieras. Puede generar una imagen de carga agradable en Ajaxload.info , si lo desea.

Luego, puede usar algo como lo siguiente para que se muestre automáticamente al enviar solicitudes Ajax:

 $(document).ready(function () { $('#spinner').bind("ajaxSend", function() { $(this).show(); }).bind("ajaxComplete", function() { $(this).hide(); }); }); 

Simplemente agregue este bloque Javascript al final de su página antes de cerrar su etiqueta corporal o donde lo considere oportuno.

Ahora, cada vez que envíe solicitudes Ajax, se #spinner div #spinner . Cuando se complete la solicitud, se ocultará nuevamente.

Si está utilizando Turbolinks With Rails esta es mi solución:

Este es el CoffeeScript

 $(window).on 'page:fetch', -> $('body').append("") $('body').addClass("loading") $(window).on 'page:change', -> $('body').removeClass("loading") 

Este es el SASS CSS basado en la primera respuesta excelente de Jonathan Sampson

 # loader.css.scss .modal { display: none; position: fixed; z-index: 1000; top: 0; left: 0; height: 100%; width: 100%; background: rgba( 255, 255, 255, 0.4) asset-url('ajax-loader.gif', image) 50% 50% no-repeat; } body.loading { overflow: hidden; } body.loading .modal { display: block; } 

Al igual que Mark H, dijo que BlockUI es el camino.

Ex.:

   

Obs .: Obtuve el ajax-loader.gif en http://www.ajaxload.info/

Con todo el respeto debido a otras publicaciones, tiene aquí una solución muy simple, usando CSS3 y jQuery, sin usar ningún otro recurso externo ni archivos.

 $('#submit').click(function(){ $(this).addClass('button_loader').attr("value",""); window.setTimeout(function(){ $('#submit').removeClass('button_loader').attr("value","\u2713"); $('#submit').prop('disabled', true); }, 3000); }); 
 #submit:focus{ outline:none; outline-offset: none; } .button { display: inline-block; padding: 6px 12px; margin: 20px 8px; font-size: 14px; font-weight: 400; line-height: 1.42857143; text-align: center; white-space: nowrap; vertical-align: middle; -ms-touch-action: manipulation; cursor: pointer; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; background-image: none; border: 2px solid transparent; border-radius: 5px; color: #000; background-color: #b2b2b2; border-color: #969696; } .button_loader { background-color: transparent; border: 4px solid #f3f3f3; border-radius: 50%; border-top: 4px solid #969696; border-bottom: 4px solid #969696; width: 35px; height: 35px; -webkit-animation: spin 0.8s linear infinite; animation: spin 0.8s linear infinite; } @-webkit-keyframes spin { 0% { -webkit-transform: rotate(0deg); } 99% { -webkit-transform: rotate(360deg); } } @keyframes spin { 0% { transform: rotate(0deg); } 99% { transform: rotate(360deg); } } 
   

tenga en cuenta que al usar asp.net mvc, con “using (Ajax.BeginForm (…” configurando “ajaxStart” no funcionará).

Usa los ajaxotions para superar este problema:

 (Ajax.BeginForm("ActionName", new AjaxOptions { OnBegin = "uiOfProccessingAjaxAction", OnComplete = "uiOfProccessingAjaxActionComplete" })) 

Esto haría desaparecer los botones, luego una animación de “carga” aparecería en su lugar y finalmente solo mostraría un mensaje de éxito.

 $(function(){ $('#submit').click(function(){ $('#submit').hide(); $("#form .buttons").append('Loading...'); $.post("sendmail.php", {emailFrom: nameVal, subject: subjectVal, message: messageVal}, function(data){ jQuery("#form").slideUp("normal", function() { $("#form").before('

Success

Your email was sent.

'); }); } ); }); });

La mayoría de las soluciones que he visto nos permiten diseñar una superposición de carga, mantenerla oculta y luego mostrarla cuando sea necesario, o mostrar un gif o imagen, etc.

Quería desarrollar un complemento robusto donde con una simple llamada jQuery puedo mostrar la pantalla de carga y derribarla cuando la tarea se completa.

A continuación está el código. Depende de Font awesome y jQuery:

 /** * Raj: Used basic sources from here: http://jsfiddle.net/eys3d/741/ **/ (function($){ // Retain count concept: http://stackoverflow.com/a/2420247/260665 // Callers should make sure that for every invocation of loadingSpinner method there has to be an equivalent invocation of removeLoadingSpinner var retainCount = 0; // http://stackoverflow.com/a/13992290/260665 difference between $.fn.extend and $.extend $.extend({ loadingSpinner: function() { // add the overlay with loading image to the page var over = '
' + ''+ '
'; if (0===retainCount) { $(over).appendTo('body'); } retainCount++; }, removeLoadingSpinner: function() { retainCount--; if (retainCount< =0) { $('#custom-loading-overlay').remove(); retainCount = 0; } } }); }(jQuery));

Simplemente ponga lo anterior en un archivo js e inclúyalo a lo largo del proyecto.

Invocación:

 $.loadingSpinner(); $.removeLoadingSpinner(); 

Según https://www.w3schools.com/howto/howto_css_loader.asp , este es un proceso de 2 pasos sin JS:

1.Agrega este HTML donde quieras el spinner:

2. Añadir este CSS para hacer el spinner actual:

 .loader { border: 16px solid #f3f3f3; /* Light grey */ border-top: 16px solid #3498db; /* Blue */ border-radius: 50%; width: 120px; height: 120px; animation: spin 2s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } 

Yo uso CSS3 para animación

 /************ CSS3 *************/ .icon-spin { font-size: 1.5em; display: inline-block; animation: spin1 2s infinite linear; } @keyframes spin1{ 0%{transform:rotate(0deg)} 100%{transform:rotate(359deg)} } /************** CSS3 cross-platform ******************/ .icon-spin-cross-platform { font-size: 1.5em; display: inline-block; -moz-animation: spin 2s infinite linear; -o-animation: spin 2s infinite linear; -webkit-animation: spin 2s infinite linear; animation: spin2 2s infinite linear; } @keyframes spin2{ 0%{transform:rotate(0deg)} 100%{transform:rotate(359deg)} } @-moz-keyframes spin2{ 0%{-moz-transform:rotate(0deg)} 100%{-moz-transform:rotate(359deg)} } @-webkit-keyframes spin2{ 0%{-webkit-transform:rotate(0deg)} 100%{-webkit-transform:rotate(359deg)} } @-o-keyframes spin2{ 0%{-o-transform:rotate(0deg)} 100%{-o-transform:rotate(359deg)} } @-ms-keyframes spin2{ 0%{-ms-transform:rotate(0deg)} 100%{-ms-transform:rotate(359deg)} } 
  
Default CSS3
Cross-Platform CSS3