ejemplos - ¿Cómo puedo crear una animación "Por favor, espere, cargando..." usando jQuery?
jquery animation slide (14)
Como dijo Mark H, la blockUI es el camino.
Ex.:
<script type="text/javascript" src="javascript/jquery/jquery.blockUI.js"></script>
<script>
// unblock when ajax activity stops
$(document).ajaxStop($.unblockUI);
$("#downloadButton").click(function() {
$("#dialog").dialog({
width:"390px",
modal:true,
buttons: {
"OK, AGUARDO O E-MAIL!": function() {
$.blockUI({ message: ''<img src="img/ajax-loader.gif" />'' });
send();
}
}
});
});
function send() {
$.ajax({
url: "download-enviar.do",
type: "POST",
blablabla
});
}
</script>
Obs .: Tengo el archivo ajax-loader.gif en http://www.ajaxload.info/
Me gustaría colocar en mi sitio una animación de círculo giratorio "por favor espere, cargando". ¿Cómo debo lograr esto usando jQuery?
Con el debido respeto a otras publicaciones, tiene aquí una solución muy simple, utilizando CSS3 y jQuery, sin utilizar ningún otro recurso o archivo externo.
$(''#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); }
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input id="submit" class="button" type="submit" value="Submit" />
En cuanto a la imagen de carga real, echa un vistazo a 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) Utilice ajaxStart y ajaxComplete :
$(''#wait'').ajaxStart(function() {
$(this).show();
}).ajaxComplete(function() {
$(this).hide();
});
Usando esto, el elemento se mostrará / ocultará para cualquier solicitud. Puede ser bueno o malo, dependiendo de la necesidad.
C) Utilice 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;
});
Esto haría que los botones desaparezcan, luego aparecerá una animación de "carga" en su lugar y, finalmente, solo mostrará un mensaje de éxito.
$(function(){
$(''#submit'').click(function(){
$(''#submit'').hide();
$("#form .buttons").append(''<img src="assets/img/loading.gif" alt="Loading..." id="loading" />'');
$.post("sendmail.php",
{emailFrom: nameVal, subject: subjectVal, message: messageVal},
function(data){
jQuery("#form").slideUp("normal", function() {
$("#form").before(''<h1>Success</h1><p>Your email was sent.</p>'');
});
}
);
});
});
Junto con lo que Jonathan y Samir sugirieron (¡ambas respuestas excelentes por cierto!), JQuery tiene algunos eventos integrados que se activarán para usted al realizar una solicitud de ajax.
Ahí está el evento ajaxStart
Muestra un mensaje de carga cada vez que se inicia una solicitud AJAX (y ninguna ya está activa).
... y es hermano, el evento ajaxStop
Adjunte una función para que se ejecute siempre que todas las solicitudes AJAX hayan finalizado. Este es un evento de Ajax.
Juntos, son una buena manera de mostrar un mensaje de progreso cuando se produce cualquier actividad ajax en cualquier lugar de la página.
HTML:
<div id="loading">
<p><img src="loading.gif" /> Please Wait</p>
</div>
Guión:
$(document).ajaxStart(function(){
$(''#loading'').show();
}).ajaxStop(function(){
$(''#loading'').hide();
});
La excelente solución de Jonathon se rompe en IE8 (la animación no se muestra en absoluto). Para arreglar esto, cambia 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)};
La mayoría de las soluciones que he visto esperan que diseñemos una capa de carga, la mantengamos oculta y luego la mostremos cuando sea necesario, o mostremos un gif o una imagen, etc.
Quería desarrollar un complemento robusto, donde con una simple llamada jQuery puedo mostrar la pantalla de carga y arrancarla cuando se complete la tarea.
A continuación se muestra 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://.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://.com/a/13992290/260665 difference between $.fn.extend and $.extend
$.extend({
loadingSpinner: function() {
// add the overlay with loading image to the page
var over = ''<div id="custom-loading-overlay">'' +
''<i id="custom-loading" class="fa fa-spinner fa-spin fa-3x fa-fw" style="font-size:48px; color: #470A68;"></i>''+
''</div>'';
if (0===retainCount) {
$(over).appendTo(''body'');
}
retainCount++;
},
removeLoadingSpinner: function() {
retainCount--;
if (retainCount<=0) {
$(''#custom-loading-overlay'').remove();
retainCount = 0;
}
}
});
}(jQuery));
Simplemente coloque lo anterior en un archivo js e inclúyalo en todo el proyecto.
Invocación:
$.loadingSpinner();
$.removeLoadingSpinner();
Puede capturar un GIF animado de un círculo giratorio de Ajaxload : colóquelo en algún lugar de la jerarquía de archivos de su 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(''<div id="loading-image"><img src="path/to/loading.gif" alt="Loading..." /></div>'');
}
function hideLoadingImage() {
$(''#loading-image'').remove();
}
Entonces solo necesitas usar estos métodos en tu 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, tendrá que hacer un seguimiento de cuántas llamadas se están ejecutando a la vez de alguna manera, y solo ocultarse 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, deberá buscar $.ajax
, que es más complejo que $.load
, $.get
y similares, pero también mucho más flexible.
Según https://www.w3schools.com/howto/howto_css_loader.asp , este es un proceso de 2 pasos sin JS:
1.Agregue este HTML donde desee que aparezca la rueda giratoria: <div class="loader"></div>
2.Agregue este CSS para hacer el giro real:
.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); }
}
Si está utilizando Turbolinks con rieles, esta es mi solución:
Este es el CoffeeScript
$(window).on ''page:fetch'', ->
$(''body'').append("<div class=''modal''></div>")
$(''body'').addClass("loading")
$(window).on ''page:change'', ->
$(''body'').removeClass("loading")
Este es el SASS CSS basado en la primera excelente respuesta 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;
}
Tenga en cuenta que al usar ASP.Net MVC, al using (Ajax.BeginForm(...
, la configuración de ajaxStart
no funcionará.
Utilice las AjaxOptions
para superar este problema:
(Ajax.BeginForm("ActionName", new AjaxOptions { OnBegin = "uiOfProccessingAjaxAction", OnComplete = "uiOfProccessingAjaxActionComplete" }))
Usted podría hacer esto de diferentes maneras. Podría ser un estado sutil como pequeño en la página que dice "Cargando ...", o tan fuerte como un elemento entero que enturbia la página mientras se cargan los nuevos datos. 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" de http://ajaxload.info que usaré
Vamos a crear un elemento que podamos mostrar / ocultar cada vez que realicemos una solicitud ajax:
<div class="modal"><!-- Place at bottom of page --></div>
El CSS
A continuación vamos a darle un poco de estilo:
/* 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 por último, la jQuery.
Muy bien, a la jQuery. Esta siguiente parte es realmente muy simple:
$body = $("body");
$(document).on({
ajaxStart: function() { $body.addClass("loading"); },
ajaxStop: function() { $body.removeClass("loading"); }
});
¡Eso es! Estamos adjuntando algunos eventos al elemento del cuerpo en cualquier momento que se ajaxStop
eventos ajaxStart
o ajaxStop
. Cuando se inicia un evento ajax, agregamos la clase "cargando" al cuerpo. y cuando los eventos se realizan, eliminamos la clase de "carga" del cuerpo.
Véalo en acción: http://jsfiddle.net/VpDUG/4952/
Yo uso CSS3 para la 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)}
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="row">
<div class="col-md-6">
Default CSS3
<span class="glyphicon glyphicon-repeat icon-spin"></span>
</div>
<div class="col-md-6">
Cross-Platform CSS3
<span class="glyphicon glyphicon-repeat icon-spin-cross-platform"></span>
</div>
</div>
jQuery proporciona enlaces de eventos para cuando las solicitudes de AJAX comienzan y terminan. Puede enganchar en estos para mostrar su cargador.
Por ejemplo, crea el siguiente div:
<div id="spinner">
<img src="images/spinner.gif" alt="Loading" />
</div>
Configúrelo para display: none
en sus hojas de estilo. Puedes diseñarlo como quieras. Puede generar una buena imagen de carga en Ajaxload.info , si lo desea.
Luego, puede usar algo como lo siguiente para que se muestre automáticamente al enviar solicitudes de Ajax:
$(document).ready(function () {
$(''#spinner'').bind("ajaxSend", function() {
$(this).show();
}).bind("ajaxComplete", function() {
$(this).hide();
});
});
Simplemente agregue este bloque de Javascript al final de su página antes de cerrar la etiqueta de su cuerpo o donde lo considere oportuno.
Ahora, cada vez que envíe solicitudes de Ajax, se #spinner
div #spinner
. Cuando la solicitud esté completa, se ocultará de nuevo.