Nel Prototipo Posso mostrare un'immagine "loading ..." con questo codice:
var myAjax = new Ajax.Request( url, {method: 'get', parameters: pars,
onLoading: showLoad, onComplete: showResponse} );
function showLoad () {
...
}
Nel jQuery, Posso caricare una pagina del server in un elemento con questo:
$('#message').load('index.php?pg=ajaxFlashcard');
ma come posso allegare un cursore di caricamento a questo comando come ho fatto in Prototype?
Ci sono un paio di modi. Il mio modo preferito è quello di associare 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 effettuano chiamate Ajax.
Aggiornamento : A partire da jQuery 1.8, la documentazione afferma che .ajaxStart/Stop
deve essere collegato solo a document
. Ciò trasformerebbe il frammento di cui sopra in:
var $loading = $('#loadingDiv').hide();
$(document)
.ajaxStart(function () {
$loading.show();
})
.ajaxStop(function () {
$loading.hide();
});
Per jQuery che uso
jQuery.ajaxSetup({
beforeSend: function() {
$('#loader').show();
},
complete: function(){
$('#loader').hide();
},
success: function() {}
});
Puoi semplicemente usare la funzione .ajax
di jQuery e usare la sua opzione beforeSend
e definire alcune funzioni in cui puoi mostrare qualcosa come un div di loader e in caso di successo puoi nascondere quel caricatore div.
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 Gif Spinning. Ecco un sito Web che è un ottimo AJAX Loader Generator in base alla combinazione di colori: http://ajaxload.info/
Puoi inserire l'immagine animata nel DOM subito prima della chiamata AJAX e fare una funzione in linea 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 su richieste successive (se ciò è importante). Nota che le vecchie versioni di IE potrebbero avere difficoltà con l'animazione.
In bocca al lupo!
$('#message').load('index.php?pg=ajaxFlashcard', null, showResponse);
showLoad();
function showResponse() {
hideLoad();
...
}
Se stai usando $.ajax()
puoi usare qualcosa di simile a questo:
$.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'
});
Usa il plugin di caricamento: http://plugins.jquery.com/project/loading
$.loading.onAjax({img:'loading.gif'});
Variante: ho un'icona con id = "logo" in alto a sinistra nella pagina principale; uno spinner gif viene quindi sovrapposto in cima (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() {}
});
Voglio anche contribuire a questa risposta. Stavo cercando qualcosa di simile in jQuery e questo quello che alla fine ho usato.
Ho ottenuto il mio spinner di caricamento da http://ajaxload.info/ . La mia soluzione si basa su questa semplice risposta a http://christierney.com/2011/03/23/global-ajax-loading-spinners/ .
Fondamentalmente il tuo markup HTML e CSS assomiglieranno 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 :)
Ho finito con due modifiche alla risposta originale .
document
. Ciò rende più difficile filtrare solo alcune delle richieste Ajax. Soo ...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();
})
Puoi semplicemente assegnare un'immagine caricatore allo stesso tag su cui successivamente caricerai 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.
Oltre a impostare i valori predefiniti globali per eventi ajax, puoi impostare il comportamento per elementi specifici. Forse basta cambiare la loro classe sarebbe sufficiente?
$('#myForm').ajaxSend( function() {
$(this).addClass('loading');
});
$('#myForm').ajaxComplete( function(){
$(this).removeClass('loading');
});
Esempio di 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;
}
$('#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>');
}
});
Si noti che è necessario utilizzare le chiamate asincrone per gli spinners per funzionare (almeno questo è ciò che ha causato il mio non mostrare fino a dopo la chiamata ajax e poi rapidamente andato via al termine della chiamata 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
}
});
Ho usato quanto segue con jQuery UI Dialog. (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...'
});
Il contiene una gif di caricamento animata fino a quando il suo contenuto non viene sostituito quando la chiamata ajax viene completata.
$.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;
});
#loading { background: url(/image/loading.gif) no-repeat center; }
Questo è un plugin molto semplice e intelligente per lo scopo specifico: https://github.com/hekigan/is-loading
Se si prevede di utilizzare un caricatore ogni volta che si effettua una richiesta server, è possibile utilizzare il seguente schema.
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");
});
In particolare, questo codice utilizza il plugin jajaxloader (che ho appena creato)
Se non vuoi scrivere il tuo codice, ci sono anche molti plugin che fanno proprio questo:
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);
}
});
Penso che tu abbia ragione. Questo metodo è troppo globale ...
Tuttavia, è un buon valore predefinito quando la chiamata AJAX non ha alcun effetto sulla pagina stessa. (lo sfondo salva ad esempio). (puoi sempre spegnerlo per una determinata chiamata ajax passando "globale": false - vedi documentazione a jquery
Quando la chiamata AJAX ha lo scopo di aggiornare parte della pagina, mi piace che le mie immagini di "caricamento" siano specifiche per la sezione aggiornata. Mi piacerebbe vedere quale parte è aggiornata.
Immagina quanto sarebbe bello se tu potessi semplicemente scrivere qualcosa come:
$("#component_to_refresh").ajax( { ... } );
E questo mostrerebbe un "caricamento" in questa sezione. Di seguito è riportata una funzione che ho scritto che gestisce anche la visualizzazione di "caricamento", ma è specifica per l'area che si sta aggiornando in ajax.
Per prima cosa, 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);
};
Il mio codice Ajax sembra così, in effetti, ho appena commentato asincrono: la linea falsa e lo spinner appaiono.
$.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 classe impressionante di font:
<i id="ajaxspinner" class="fas fa-spinner fa-spin fa-3x fa-fw" style="display:none"></i>
Spero che aiuti qualcuno.
Puoi sempre usare Bloccare plugin UI jQuery che fa tutto per te, e blocca anche la pagina di qualsiasi input mentre l'Ajax si sta caricando. Nel caso in cui il plugin sembra non funzionare, puoi leggere il modo corretto di usarlo in questa risposta. Controlla.