web-dev-qa-db-fra.com

Comment créer une animation "Veuillez patienter, Chargement ..." à l'aide de jQuery?

Je souhaite placer une animation "s'il vous plaît patienter, chargement" sur mon site. Comment dois-je accomplir cela en utilisant jQuery?

559
thedp

Vous pouvez le faire de différentes manières. Cela peut être aussi subtil qu'un petit statut sur la page disant "Chargement en cours ...", ou aussi fort qu'un élément entier grisant la page pendant le chargement des nouvelles données. L'approche que je suis en train de suivre vous montrera comment accomplir les deux méthodes.

La mise en place

Commençons par nous procurer une belle animation de "chargement" de http://ajaxload.info enter image description here

Créons un élément que nous pouvons afficher/masquer à tout moment lorsque nous faisons une demande ajax:

<div class="modal"><!-- Place at bottom of page --></div>

Le CSS

Ensuite donnons du flair:

/* 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;
}

Et enfin, le jQuery

Bon, passons au jQuery. Cette partie suivante est réellement très simple:

$body = $("body");

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

C'est ça! Nous attachons des événements à l'élément body chaque fois que les événements ajaxStart ou ajaxStop sont déclenchés. Quand un événement ajax commence, nous ajoutons la classe "loading" au corps. et lorsque les événements sont terminés, nous retirons la classe "loading" du corps.

Voyez-le en action: http://jsfiddle.net/VpDUG/4952/

1174
Sampson

En ce qui concerne l'image de chargement réelle, consultez ce site pour un tas d'options.

En ce qui concerne l'affichage d'une DIV avec cette image au début d'une demande, vous avez plusieurs choix:

A) Afficher et masquer manuellement l'image:

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

B) Utilisez ajaxStart et ajaxComplete :

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

En utilisant cela, l'élément affichera/cachera pour toute requête . Pourrait être bon ou mauvais, selon les besoins.

C) Utilisez des rappels individuels pour une demande particulière:

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

En plus de ce que Jonathan et Samir ont suggéré (d'excellentes réponses d'ailleurs!), JQuery a quelques événements intégrés qu'il déclenchera pour vous lors d'une demande ajax.

Il y a l'événement ajaxStart

Afficher un message de chargement chaque fois qu'une demande AJAX commence (et qu'aucune n'est déjà active).

... et c'est frère, l'événement ajaxStop

Attachez une fonction à exécuter à la fin de toutes les demandes AJAX. Ceci est un événement Ajax.

Ensemble, ils constituent un moyen efficace d'afficher un message de progression lorsqu'une activité ajax se produit n'importe où sur la page.

HTML:

<div id="loading">
  <p><img src="loading.gif" /> Please Wait</p>
</div>

Scénario:

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

Vous pouvez récupérer un fichier GIF animé représentant un cercle en rotation entre Ajaxload - et le coller quelque part dans la hiérarchie des fichiers de votre site Web. Ensuite, vous devez simplement ajouter un élément HTML avec le code correct et le supprimer lorsque vous avez terminé. C'est assez simple:

_function showLoadingImage() {
    $('#yourParentElement').append('<div id="loading-image"><img src="path/to/loading.gif" alt="Loading..." /></div>');
}

function hideLoadingImage() {
    $('#loading-image').remove();
}
_

Il vous suffit ensuite d'utiliser ces méthodes dans votre appel 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();
_

Cela comporte quelques réserves: tout d’abord, si vous avez deux ou plusieurs endroits où l’image de chargement peut être affichée, vous devrez connaître le nombre d’appels en cours, et ne les cacher que lorsqu’ils sont en cours. terminé. Cela peut être fait en utilisant un simple compteur, qui devrait fonctionner dans presque tous les cas.

Deuxièmement, cela ne fera que masquer l'image de chargement lors d'un appel réussi AJAX. Pour gérer les états d'erreur, vous devez vous pencher sur $.ajax , qui est plus complexe que _$.load_, _$.get_ et similaires, mais beaucoup plus flexible aussi.

18
Samir Talwar

L'excellente solution de Jonathon tombe dans IE8 (l'animation ne s'affiche pas du tout). Pour résoudre ce problème, changez le CSS en:

.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)};
15
Ben Power

jQuery fournit des hooks d'événement pour quand AJAX demande le début et la fin. Vous pouvez y accrocher pour montrer votre chargeur.

Par exemple, créez le div suivant:

<div id="spinner">
  <img src="images/spinner.gif" alt="Loading" />
</div>

Réglez-le sur display: none dans vos feuilles de style. Vous pouvez l'appeler comme vous le souhaitez. Vous pouvez générer une image de chargement Nice à l’adresse Ajaxload.info , si vous le souhaitez.

Ensuite, vous pouvez utiliser quelque chose comme ce qui suit pour le faire apparaître automatiquement lors de l'envoi de demandes Ajax:

$(document).ready(function () {

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

});

Ajoutez simplement ce bloc Javascript à la fin de votre page avant de fermer votre balise body ou où bon vous semble.

Maintenant, chaque fois que vous envoyez des requêtes Ajax, le #spinner div sera affiché. Une fois la demande terminée, elle sera à nouveau masquée.

6
Veeti

Si vous utilisez Turbolinks With Rails, voici ma solution:

C'est le CoffeeScript

$(window).on 'page:fetch', ->
  $('body').append("<div class='modal'></div>")
  $('body').addClass("loading")

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

Ceci est le CSS SASS basé sur la première excellente réponse 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;
}
6
Fred

Comme Mark H a dit le blockUI est le chemin.

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 .: J'ai le ajax-loader.gif sur http://www.ajaxload.info/

5
bpedroso

En tout respect pour les autres publications, vous avez ici une solution très simple, utilisant CSS3 et jQuery, sans utiliser d'autres ressources ni fichiers externes.

$('#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" />

La plupart des solutions que j'ai vues attendent que nous concevions un calque de chargement, le masquions puis le masquiez au besoin, ou que vous montriez un gif, une image, etc.

Je voulais développer un plugin robuste où, avec un simple appel jQuery, je peux afficher l'écran de chargement et le supprimer lorsque la tâche est terminée.

Ci-dessous le code. Cela dépend de Font awesome et de 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 = '<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)); 

Il suffit de mettre ce qui précède dans un fichier js et de l’inclure tout au long du projet.

Invocation:

$.loadingSpinner();
$.removeLoadingSpinner();
3
Raj Pawan Gumdal

Cela ferait disparaître les boutons, puis une animation de "chargement" apparaîtrait à leur place et afficherait finalement un message de réussite.

$(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>');
                    });
                }
        );
    });
});
3
Tsundoku

Notez que lorsque vous utilisez ASP.Net MVC, avec using (Ajax.BeginForm(..., le réglage de ajaxStart ne fonctionnera pas.

Utilisez la AjaxOptions pour résoudre ce problème:

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

J'utilise CSS3 pour l'animation

/************ 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>
1
Camille

Par https://www.w3schools.com/howto/howto_css_loader.asp , il s'agit d'un processus en 2 étapes sans JS:

1.Ajouter ce HTML où vous voulez le spinner: <div class="loader"></div>

2.Ajouter ce CSS pour faire le spinner réel:

.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); }
}
1
hamx0r