web-dev-qa-db-fra.com

Comment afficher le chargement de spinner dans jQuery?

Dans Prototype Je peux montrer une image de "chargement ..." avec ce code:

var myAjax = new Ajax.Request( url, {method: 'get', parameters: pars, 
onLoading: showLoad, onComplete: showResponse} );

function showLoad () {
    ...
}

Dans jQuery, Je peux charger une page de serveur dans un élément avec ceci:

$('#message').load('index.php?pg=ajaxFlashcard');

mais comment puis-je attacher un spinner de chargement à cette commande comme je l'ai fait dans Prototype?

391
Edward Tanguay

Il y a deux façons. Ma méthode préférée consiste à attacher une fonction aux événements ajaxStart/Stop sur l'élément lui-même.

$('#loadingDiv')
    .hide()  // Hide it initially
    .ajaxStart(function() {
        $(this).show();
    })
    .ajaxStop(function() {
        $(this).hide();
    })
;

Les fonctions ajaxStart/Stop se déclenchent chaque fois que vous effectuez un appel Ajax.

Mise à jour: À partir de jQuery 1.8, la documentation indique que .ajaxStart/Stop ne devrait être associé qu'à document. Cela transformerait l'extrait ci-dessus en:

var $loading = $('#loadingDiv').hide();
$(document)
  .ajaxStart(function () {
    $loading.show();
  })
  .ajaxStop(function () {
    $loading.hide();
  });
774
nickf

Pour jQuery j'utilise

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

Vous pouvez simplement utiliser la fonction .ajax de jQuery et son option beforeSendet définir une fonction dans laquelle vous pouvez afficher quelque chose comme un div de chargeur et en cas de succès, vous pouvez masquer ce div de chargeur.

jQuery.ajax({
    type: "POST",
    url: 'YOU_URL_TO_WHICH_DATA_SEND',
    data:'YOUR_DATA_TO_SEND',
    beforeSend: function() {
        $("#loaderDiv").show();
    },
    success: function(data) {
        $("#loaderDiv").hide();
    }
});

Vous pouvez avoir n'importe quelle image Spinning Gif. Voici un excellent site AJAX Loader Generator en fonction de votre palette de couleurs: http://ajaxload.info/

37
Seeker

Vous pouvez insérer l'image animée dans le DOM juste avant l'appel AJAX, et créer une fonction en ligne pour la supprimer ...

$("#myDiv").html('<img src="images/spinner.gif" alt="Wait" />');
$('#message').load('index.php?pg=ajaxFlashcard', null, function() {
  $("#myDiv").html('');
});

Cela garantira que votre animation commence à la même image lors des demandes suivantes (si cela compte). Notez que les anciennes versions de IE pourraient ont des difficultés avec l'animation.

Bonne chance!

22
Josh Stodola
$('#message').load('index.php?pg=ajaxFlashcard', null, showResponse);
showLoad();

function showResponse() {
    hideLoad();
    ...
}

http://docs.jquery.com/Ajax/load#urldatacallback

20
Brent

Si vous utilisez $.ajax(), vous pouvez utiliser quelque chose comme ceci:

$.ajax({
        url: "destination url",
        success: sdialog,
        error: edialog,
        // shows the loader element before sending.
        beforeSend: function () { $("#imgSpinner1").show(); },
        // hides the loader after completion of request, whether successfull or failor.             
        complete: function () { $("#imgSpinner1").hide(); },             
        type: 'POST', dataType: 'json'
    });  
15
Amin Saqi

Utilisez le plugin de chargement: http://plugins.jquery.com/project/loading

$.loading.onAjax({img:'loading.gif'});
10
Nathan Bubna

Variante: j'ai une icône avec id = "logo" en haut à gauche de la page principale; un spinner gif est ensuite superposé (avec une transparence) lorsque Ajax fonctionne.

jQuery.ajaxSetup({
  beforeSend: function() {
     $('#logo').css('background', 'url(images/ajax-loader.gif) no-repeat')
  },
  complete: function(){
     $('#logo').css('background', 'none')
  },
  success: function() {}
});
8
Paul

Je veux aussi contribuer à cette réponse. Je cherchais quelque chose de similaire dans jQuery et c'est ce que j'ai finalement utilisé.

J'ai eu mon spinner de chargement de http://ajaxload.info/ . Ma solution est basée sur cette réponse simple à l'adresse http://christierney.com/2011/03/23/global-ajax-loading-spinners/ .

En gros, votre balisage HTML et CSS ressemblent à ceci:

<style>
     #ajaxSpinnerImage {
          display: none;
     }
</style>

<div id="ajaxSpinnerContainer">
     <img src="~/Content/ajax-loader.gif" id="ajaxSpinnerImage" title="working..." />
</div>

Et ensuite, votre code pour jQuery ressemblerait à ceci:

<script>
     $(document).ready(function () {
          $(document)
          .ajaxStart(function () {
               $("#ajaxSpinnerImage").show();
          })
          .ajaxStop(function () {
               $("#ajaxSpinnerImage").hide();
          });

          var owmAPI = "http://api.openweathermap.org/data/2.5/weather?q=London,uk&APPID=YourAppID";
          $.getJSON(owmAPI)
          .done(function (data) {
               alert(data.coord.lon);
          })
          .fail(function () {
               alert('error');
          });
     });
</script>

C'est aussi simple que ça :)

7
Brendan Vogt

Je me suis retrouvé avec deux modifications à la réponse d'origine .

  1. Depuis jQuery 1.8, ajaxStart et ajaxStop ne doivent être associés qu'à document. Cela rend plus difficile de filtrer uniquement certaines des requêtes ajax. Soo ...
  2. Le passage à ajaxSend et ajaxComplete permet de réaliser une intersection de la requête ajax en cours avant d'afficher le compteur.

Voici le code après ces modifications:

$(document)
    .hide()  // hide it initially
    .ajaxSend(function(event, jqxhr, settings) {
        if (settings.url !== "ajax/request.php") return;
        $(".spinner").show();
    })
    .ajaxComplete(function(event, jqxhr, settings) {
        if (settings.url !== "ajax/request.php") return;
        $(".spinner").hide();
    })
7
Emil Stenström

Vous pouvez simplement assigner une image de chargeur à la même balise sur laquelle vous allez ultérieurement charger du contenu à l'aide d'un appel Ajax:

$("#message").html('<span>Loading...</span>');

$('#message').load('index.php?pg=ajaxFlashcard');

Vous pouvez également remplacer la balise span par une balise image.

7
Umesh kumar

Outre la définition de valeurs globales par défaut pour les événements ajax, vous pouvez également définir le comportement d'éléments spécifiques. Peut-être que changer de classe suffirait?

$('#myForm').ajaxSend( function() {
    $(this).addClass('loading');
});
$('#myForm').ajaxComplete( function(){
    $(this).removeClass('loading');
});

Exemple CSS, pour cacher #myForm avec un spinner:

.loading {
    display: block;
    background: url(spinner.gif) no-repeat center middle;
    width: 124px;
    height: 124px;
    margin: 0 auto;
}
/* Hide all the children of the 'loading' element */
.loading * {
    display: none;  
}
6
LeeGee
$('#loading-image').html('<img src="/images/ajax-loader.gif"> Sending...');

        $.ajax({
            url:  uri,
            cache: false,
            success: function(){
                $('#loading-image').html('');           
            },

           error:   function(jqXHR, textStatus, errorThrown) {
            var text =  "Error has occured when submitting the job: "+jqXHR.status+ " Contact IT dept";
           $('#loading-image').html('<span style="color:red">'+text +'  </span>');

            }
        });
4
Izabela Skibinska

Notez que vous devez utiliser des appels asynchrones pour que les filateurs fonctionnent (du moins, c’est ce qui a empêché le mien de s’afficher avant l’appel ajax, puis s’est rapidement éloigné, l’appel étant terminé et le spinner retiré).

$.ajax({
        url: requestUrl,
        data: data,
        dataType: 'JSON',
        processData: false,
        type: requestMethod,
        async: true,                         <<<<<<------ set async to true
        accepts: 'application/json',
        contentType: 'application/json',
        success: function (restResponse) {
            // something here
        },
        error: function (restResponse) {
            // something here                
        }
    });
4
Shane Rowatt

J'ai utilisé ce qui suit avec jQuery UI Dialog. (Peut-être que cela fonctionne avec d'autres callbacks ajax?)

$('<div><img src="/i/loading.gif" id="loading" /></div>').load('/ajax.html').dialog({
    height: 300,
    width: 600,
    title: 'Wait for it...'
});

Le contient un gif de chargement animé jusqu'à ce que son contenu soit remplacé à la fin de l'appel ajax.

2
Quinn Comendant

JavaScript

$.listen('click', '#captcha', function() {
    $('#captcha-block').html('<div id="loading" style="width: 70px; height: 40px; display: inline-block;" />');
    $.get("/captcha/new", null, function(data) {
        $('#captcha-block').html(data);
    }); 
    return false;
});

CSS

#loading { background: url(/image/loading.gif) no-repeat center; }
2
Jerry

C'est le meilleur moyen pour moi:

jQuery :

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

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

Café :

  $(document).ajaxStart ->
    $(".loading").show()

  $(document).ajaxStop ->
    $(".loading").hide()

Docs: ajaxStart , ajaxStop

2
Fred K

Ceci est un plugin très simple et intelligent dans ce but spécifique: https://github.com/hekigan/is-loading

2
andcl

Si vous envisagez d'utiliser un chargeur à chaque fois que vous effectuez une demande de serveur, vous pouvez utiliser le modèle suivant.

 jTarget.ajaxloader(); // (re)start the loader
 $.post('/libs/jajaxloader/demo/service/service.php', function (content) {
     jTarget.append(content); // or do something with the content
 })
 .always(function () {
     jTarget.ajaxloader("stop");
 });

Ce code utilise notamment le plugin jajaxloader (que je viens de créer)

https://github.com/lingtalfi/JAjaxLoader/

1
ling

Si vous ne voulez pas écrire votre propre code, il y a aussi beaucoup de plugins qui font exactement ça:

1
keithhackbarth

Je fais ça:

var preloaderdiv = '<div class="thumbs_preloader">Loading...</div>';
           $('#detail_thumbnails').html(preloaderdiv);
             $.ajax({
                        async:true,
                        url:'./Ajaxification/getRandomUser?top='+ $(sender).css('top') +'&lef='+ $(sender).css('left'),
                        success:function(data){
                            $('#detail_thumbnails').html(data);
                        }
             });
1
user968652

Je pense que tu as raison. Cette méthode est trop globale ...

Toutefois, il s'agit d'un bon choix par défaut lorsque votre appel AJAX n'a aucun effet sur la page elle-même. (sauvegarde de fond par exemple). (vous pouvez toujours le désactiver pour un certain appel ajax en passant "global": false - voir la documentation à jquery

Lorsque l'appel AJAX vise à actualiser une partie de la page, j'aime que mes images de "chargement" soient spécifiques à la section actualisée. J'aimerais voir quelle partie est rafraîchie.

Imaginez à quel point ce serait cool si vous pouviez simplement écrire quelque chose comme:

$("#component_to_refresh").ajax( { ... } ); 

Et cela montrerait un "chargement" sur cette section. Vous trouverez ci-dessous une fonction que j'ai écrite et qui gère le "chargement", mais elle est spécifique à la zone que vous rafraîchissez en ajax.

Tout d'abord, laissez-moi vous montrer comment l'utiliser

<!-- assume you have this HTML and you would like to refresh 
      it / load the content with ajax -->

<span id="email" name="name" class="ajax-loading">
</span>

<!-- then you have the following javascript --> 

$(document).ready(function(){
     $("#email").ajax({'url':"/my/url", load:true, global:false});
 })

Et c’est la fonction - un début simple que vous pouvez améliorer à votre guise. c'est très flexible.

jQuery.fn.ajax = function(options)
{
    var $this = $(this);
    debugger;
    function invokeFunc(func, arguments)
    {
        if ( typeof(func) == "function")
        {
            func( arguments ) ;
        }
    }

    function _think( obj, think )
    {
        if ( think )
        {
            obj.html('<div class="loading" style="background: url(/public/images/loading_1.gif) no-repeat; display:inline-block; width:70px; height:30px; padding-left:25px;"> Loading ... </div>');
        }
        else
        {
            obj.find(".loading").hide();
        }
    }

    function makeMeThink( think )
    {
        if ( $this.is(".ajax-loading") )
        {
            _think($this,think);
        }
        else
        {
            _think($this, think);
        }
    }

    options = $.extend({}, options); // make options not null - ridiculous, but still.
    // read more about ajax events
    var newoptions = $.extend({
        beforeSend: function()
        {
            invokeFunc(options.beforeSend, null);
            makeMeThink(true);
        },

        complete: function()
        {
            invokeFunc(options.complete);
            makeMeThink(false);
        },
        success:function(result)
        {
            invokeFunc(options.success);
            if ( options.load )
            {
                $this.html(result);
            }
        }

    }, options);

    $.ajax(newoptions);
};
1
guy mograbi

Mon code ajax ressemble à ceci, en effet, je viens de commenter async: false line et le spinner apparaît.

$.ajax({
        url: "@Url.Action("MyJsonAction", "Home")",
        type: "POST",
        dataType: "json",
        data: {parameter:variable},
        //async: false, 

        error: function () {
        },

        success: function (data) {
          if (Object.keys(data).length > 0) {
          //use data 
          }
          $('#ajaxspinner').hide();
        }
      });

Je montre le spinner dans une fonction avant le code ajax:

$("#MyDropDownID").change(function () {
        $('#ajaxspinner').show();

Pour HTML, j'ai utilisé une classe de polices awesome:

<i id="ajaxspinner" class="fas fa-spinner fa-spin fa-3x fa-fw" style="display:none"></i>

J'espère que ça aide quelqu'un.

1
Jaggan_j

Vous pouvez toujours utiliser Bloquer l'interface utilisateur jQuery qui fait tout pour vous, et bloque même la page de toute entrée pendant le chargement du fichier ajax. Dans le cas où le plugin semble ne pas fonctionner, vous pouvez lire sur la bonne façon de l'utiliser dans cette réponse. Vérifiez-le.

0
SamyCode