Come mostrare il caricamento del filatore in jQuery?


412

In Prototype posso mostrare un'immagine "caricamento in corso ..." con questo codice:

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

function showLoad () {
    ...
}

In jQuery , posso caricare una pagina del server in un elemento con questo:

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

ma come posso collegare uno spinner di caricamento a questo comando come ho fatto in prototipo?

Risposte:


793

Ci sono un paio di modi. Il mio modo preferito è quello di collegare una funzione agli eventi ajaxStart / Stop sull'elemento stesso.

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

Le funzioni ajaxStart / Stop si attivano ogni volta che si effettua una chiamata Ajax.

Aggiornamento : a partire da jQuery 1.8, la documentazione afferma che .ajaxStart/Stopdovrebbe essere solo allegata document. Ciò trasformerebbe lo snippet di cui sopra in:

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

48
Questo è probabilmente troppo globale per un semplice carico in un DIV.
montrealista,

363
troppo globale? quanti diversi messaggi "attendere prego" vuoi?
Nickf

23
in questo modo sfortunatamente non puoi controllare il posizionamento div di caricamento nel caso in cui non volessi mostrare solo una finestra di caricamento modale, ma
mostrala

10
ajaxStart e ajaxStop sono eventi jQuery in modo da poterli namespace: stackoverflow.com/questions/1191485/... docs.jquery.com/Namespaced_Events
David Xia

10
Se si utilizza jQuery> = 1.9, collegare gli eventi ajaxStart e ajaxStop a $ (documento). jquery.com/upgrade-guide/1.9/…
Domenic il

213

Per jQuery che uso

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

13
funziona per me, l'html dovrebbe avere qualcosa del tipo: <div id = 'loader'> <img src = "spinner.gif" /> </div>
yigal

7
Questo è stato il più pulito per me. Invece di ajaxSetup, ho inserito primaInvia: e completa: all'interno di $ ajax ({... statement.
kenswdev

4
Non so quanto valga la pena, ma jQuery menziona nella sua documentazione che l'uso di .ajaxSetup () non è raccomandato. link
pec

Nota qui che beforeSendviene chiamato prima di ogni chiamata, mentre ajaxStartviene attivato solo quando viene chiamato il primo metodo ajax. Allo stesso modo ajaxStop, viene chiamato quando termina l' ultima chiamata ajax. Se hai più di una richiesta simultanea, lo snippet in questa risposta non funzionerà correttamente.
nickf,

Non funziona per me se la chiamata ajax scade (Firefox 28 per Mac).
osa,

48

Puoi semplicemente usare la .ajaxfunzione di jQuery e usare la sua opzione beforeSende definire alcune funzioni in cui puoi mostrare qualcosa come un div del caricatore e su un'opzione di successo puoi nascondere quel div del caricatore.

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();
    }
});

Puoi avere qualsiasi immagine di Spinning Gif. Ecco un sito Web che è un ottimo generatore di caricatori AJAX secondo la tua combinazione di colori: http://ajaxload.info/


16
Il successnon sarà chiamato, se si verifica un errore, ma "riceverete sempre una completerichiamata, anche per le richieste sincrone", secondo jQuery Ajax eventi .
LeeGee,

23

Puoi inserire l'immagine animata nel DOM subito prima della chiamata AJAX ed eseguire una funzione incorporata per rimuoverla ...

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

Ciò assicurerà che l'animazione inizi nello stesso frame nelle richieste successive (se ciò è importante). Nota che le vecchie versioni di IE potrebbero avere difficoltà con l'animazione.

In bocca al lupo!


13
Suggerimento: precaricare spinner.gif in un div con display impostato su none. Altrimenti potresti ottenere un po 'di effetto ritardato dello spinner mentre lo spinner viene ancora scaricato.
uriDium,

bel suggerimento, molto più semplice rispetto all'utilizzo del plug
Gordon Thompson,

Bello! ma cara, una cosa in più che voglio visualizzare il filatore per 2 secondi anche se la pagina è già stata caricata.
Entrambi FM

5
@BothFM Perché alla gente piace aspettare le cose ...?
Josh Stodola,

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

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

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


Potresti avere problemi di tempistica lì, vero?
Tim Büthe

2
@UltimateBrent Penso che tu abbia sbagliato. Perché showLoad () non è un callback? JavaScript caricherà il contenuto in modo asincrono. showLoad () funzionerà anche prima che il contenuto sia caricato se sono corretto.
Jaseem,

2
@Jaseem Uso anche un metodo simile e in realtà si basa su chiamate asincrone. Metterei showLoad da qualche parte prima della chiamata ajax, ma il punto è mostrare uno spinner, lasciare che JS inizi la chiamata e uccidere lo spinner in un callback dopo il completamento di AJAX.
Nenotlep

17

Se stai usando $.ajax()puoi usare qualcosa del genere:

$.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'
    });  

11

Utilizzare il plug-in di caricamento: http://plugins.jquery.com/project/loading

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

10
Un plugin per questo semplice compito? Non è davvero una buona soluzione, vero? Chi vuole caricare 100 script su una pagina?
Jaseem,

2
Concordato. Comprimi e concatena, se desideri prestazioni migliori.
Nathan Bubna,

9
Non sono d'accordo: separare e modularizzare, riutilizzare il codice, se si desidera essere in grado di mantenere il proprio lavoro e farlo fare anche ad altri. Qual è la possibilità che il tuo utente abbia una connessione così scarsa che il suo client non può caricare un plugin e il tuo codice?
LeeGee,

@NathanBubna Il link è morto
SpringLearner

"Qual è la possibilità che il tuo utente abbia una connessione così scarsa che il suo client non può caricare un plugin e il tuo codice?" Abbastanza bene direi.
andrew oxenburgh

9

Variante: ho un'icona con id = "logo" nella parte superiore sinistra della pagina principale; una gif di spinner viene quindi sovrapposta in alto (con trasparenza) quando ajax sta funzionando.

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

9

Ho finito con due modifiche alla risposta originale .

  1. A partire da jQuery 1.8, ajaxStart e ajaxStop devono essere collegati solo a document. Ciò rende più difficile filtrare solo alcune delle richieste ajax. Soo ...
  2. Il passaggio a ajaxSend e ajaxComplete consente di intercettare la richiesta ajax corrente prima di mostrare lo spinner.

Questo è il codice dopo queste modifiche:

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

Bella soluzione alternativa. ajaxCompletesembra sparare prematuramente quando le richieste riprovano, quindi ho usato una combinazione di ajaxSende ajaxStopfunziona alla grande.
Mahn,

@SchweizerSchoggi: ci sono altri argomenti che rispondono a questa domanda, usa la ricerca!
Emil Stenström,

8

Voglio anche contribuire a questa risposta. Stavo cercando qualcosa di simile in jQuery e questo che alla fine ho usato.

Ho ottenuto il mio filatore di caricamento da http://ajaxload.info/ . La mia soluzione si basa su questa semplice risposta su http://christierney.com/2011/03/23/global-ajax-loading-spinners/ .

Fondamentalmente il markup HTML e CSS sarebbe simile a questo:

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

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

E quindi il codice per jQuery sarebbe simile a questo:

<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>

È così semplice :)


8

Puoi semplicemente assegnare un'immagine del caricatore allo stesso tag su cui successivamente caricherai il contenuto utilizzando una chiamata Ajax:

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

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

Puoi anche sostituire il tag span con un tag immagine.


1
Sarà difficile gestire l'interfaccia utente in questo modo. Potremmo aver bisogno di stili completamente diversi per il "caricamento" del testo e del messaggio finale. Possiamo usare il metodo di callback sopra menzionato per gestire questo problema
Jaseem

6

Oltre a impostare i valori predefiniti globali per gli eventi Ajax, è possibile impostare il comportamento per elementi specifici. Forse sarebbe sufficiente cambiare classe?

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

Esempio CSS, per nascondere #myForm con uno 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;  
}

1
Questa dovrebbe essere la risposta selezionata a mio avviso. Grazie @LeeGee.
Nam G VU,

Davvero un'ottima risposta
Raskolnikov il

4

Si noti che è necessario utilizzare le chiamate asincrone per far funzionare i filatori (almeno questo è ciò che ha causato il mio non mostrare fino a dopo la chiamata ajax e poi è andato via rapidamente quando la chiamata era terminata e rimosso lo spinner).

$.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
$('#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>');

            }
        });

Il modo più breve sarebbe quello di inserire un tag immagine con un'immagine scaricata da ajaxload.info con sfondo trasparente
Izabela Skibinska,

2

Ho usato quanto segue con la finestra di dialogo dell'interfaccia utente di jQuery. (Forse funziona con altri callback ajax?)

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

Contiene una gif di caricamento animata fino a quando il suo contenuto non viene sostituito al termine della chiamata ajax.


2

Questo è il modo migliore per me:

jQuery :

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

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

Caffè :

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

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

Documenti: ajaxStart , ajaxStop


Bene, e puoi usarlo insieme al plugin menzionato in questa risposta se vuoi ...
Matt

2

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

Questo è un plugin molto semplice e intelligente per quello scopo specifico: https://github.com/hekigan/is-loading


Veramente bello! Soprattutto se dai un'occhiata alle demo ... Disabilita gli elementi DOM, In tag, Full Overlay, Element Overlay ... fornisce tutto ciò di cui hai bisogno. E puoi facilmente combinare Full Overlay con questa risposta per farlo funzionare immediatamente.
Matt,

1

Lo faccio:

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

Penso che tu abbia ragione. Questo metodo è troppo globale ...

Tuttavia, è un buon valore predefinito per quando la chiamata AJAX non ha alcun effetto sulla pagina stessa. (ad esempio il salvataggio in background). (puoi sempre spegnerlo per una certa chiamata ajax passando "global": false - vedi la documentazione su jquery

Quando la chiamata AJAX ha lo scopo di aggiornare parte della pagina, mi piace che le mie immagini di "caricamento" siano specifiche della sezione aggiornata. Vorrei vedere quale parte è stata aggiornata.

Immagina quanto sarebbe bello se tu potessi semplicemente scrivere qualcosa del tipo:

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

E questo mostrerebbe un "caricamento" in questa sezione. Di seguito è una funzione che ho scritto che gestisce anche il "caricamento" del display ma è specifica dell'area che si sta aggiornando in ajax.

Prima di tutto, lascia che ti mostri come usarlo

<!-- 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});
 })

E questa è la funzione: un inizio di base che puoi migliorare come desideri. è molto flessibile.

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

Se si prevede di utilizzare un caricatore ogni volta che si effettua una richiesta del server, è possibile utilizzare il modello seguente.

 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");
 });

Questo codice in particolare utilizza il plugin jajaxloader (che ho appena creato)

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


1

Il mio codice Ajax si presenta così, in effetti, ho appena commentato asincrono: linea falsa e lo spinner si presenta.

$.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();
        }
      });

Sto mostrando lo spinner all'interno di una funzione prima del codice ajax:

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

Per HTML, ho usato una fantastica classe di caratteri:

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

Spero che aiuti qualcuno.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.