Antworten:
Sie können dies auf verschiedene Arten tun. Es kann subtil sein wie ein kleiner Status auf der Seite mit der Aufschrift "Laden ..." oder so laut wie ein ganzes Element, das die Seite ausgraut, während die neuen Daten geladen werden. Der folgende Ansatz zeigt Ihnen, wie Sie beide Methoden ausführen können.
Beginnen wir mit einer netten "Lade" -Animation von http://ajaxload.info, die ich verwenden werde
Lassen Sie uns ein Element erstellen, das wir jederzeit ein- / ausblenden können, wenn wir eine Ajax-Anfrage stellen:
<div class="modal"><!-- Place at bottom of page --></div>
Als nächstes geben wir ihm etwas 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;
}
Okay, weiter zur jQuery. Dieser nächste Teil ist eigentlich ganz einfach:
$body = $("body");
$(document).on({
ajaxStart: function() { $body.addClass("loading"); },
ajaxStop: function() { $body.removeClass("loading"); }
});
Das ist es! Wir befestigen einige Ereignisse an dem Körperelement zu jeder Zeit der ajaxStart
oder ajaxStop
Ereignisse ausgelöst werden. Wenn ein Ajax-Ereignis startet, fügen wir dem Körper die Klasse "Laden" hinzu. und wenn Ereignisse abgeschlossen sind, entfernen wir die Klasse "Laden" aus dem Körper.
Sehen Sie es in Aktion: http://jsfiddle.net/VpDUG/4952/
.ajaxStop()
und .ajaxStart()
nur noch an das Dokument angehängt werden. docs
In Bezug auf das tatsächliche Ladebild finden Sie auf dieser Website eine Reihe von Optionen.
Wenn Sie zu Beginn einer Anfrage einen DIV mit diesem Bild anzeigen möchten, haben Sie mehrere Möglichkeiten:
A) Zeigen und verbergen Sie das Bild manuell:
$('#form').submit(function() {
$('#wait').show();
$.post('/whatever.php', function() {
$('#wait').hide();
});
return false;
});
B) Verwenden Sie ajaxStart und ajaxComplete :
$('#wait').ajaxStart(function() {
$(this).show();
}).ajaxComplete(function() {
$(this).hide();
});
Mit dieser Option wird das Element für jede Anforderung ein- / ausgeblendet . Kann je nach Bedarf gut oder schlecht sein.
C) Verwenden Sie einzelne Rückrufe für eine bestimmte Anfrage:
$('#form').submit(function() {
$.ajax({
url: '/whatever.php',
beforeSend: function() { $('#wait').show(); },
complete: function() { $('#wait').hide(); }
});
return false;
});
Zusammen mit dem, was Jonathan und Samir vorgeschlagen haben (beide ausgezeichnete Antworten übrigens!), Hat jQuery einige integrierte Ereignisse, die bei einer Ajax-Anfrage für Sie ausgelöst werden.
Da ist die ajaxStart
Veranstaltung
Zeigen Sie eine Lademeldung an, wenn eine AJAX-Anforderung gestartet wird (und keine bereits aktiv ist).
... und es ist Bruder, das ajaxStop
Ereignis
Fügen Sie eine Funktion hinzu, die ausgeführt werden soll, wenn alle AJAX-Anforderungen beendet wurden. Dies ist ein Ajax-Ereignis.
Zusammen bieten sie eine gute Möglichkeit, eine Fortschrittsmeldung anzuzeigen, wenn eine Ajax-Aktivität irgendwo auf der Seite stattfindet.
HTML:
<div id="loading">
<p><img src="loading.gif" /> Please Wait</p>
</div>
Skript:
$(document).ajaxStart(function(){
$('#loading').show();
}).ajaxStop(function(){
$('#loading').hide();
});
.ajaxStart
kann nur an Dokument angehängt werden, dh. $(document).ajaxStart(function(){}).
Sie können ein animiertes GIF eines sich drehenden Kreises von Ajaxload herunterladen - kleben Sie es irgendwo in die Hierarchie Ihrer Website-Datei. Dann müssen Sie nur noch ein HTML-Element mit dem richtigen Code hinzufügen und es entfernen, wenn Sie fertig sind. Das ist ziemlich einfach:
function showLoadingImage() {
$('#yourParentElement').append('<div id="loading-image"><img src="path/to/loading.gif" alt="Loading..." /></div>');
}
function hideLoadingImage() {
$('#loading-image').remove();
}
Sie müssen dann nur noch diese Methoden in Ihrem AJAX-Aufruf verwenden:
$.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();
Dies hat einige Einschränkungen: Wenn Sie zwei oder mehr Stellen haben, an denen das Ladebild angezeigt werden kann, müssen Sie zunächst verfolgen, wie viele Anrufe gleichzeitig ausgeführt werden, und sich nur dann verstecken, wenn sie angezeigt werden alles erledigt. Dies kann mit einem einfachen Zähler erfolgen, der in fast allen Fällen funktionieren sollte.
Zweitens wird das Ladebild nur bei einem erfolgreichen AJAX-Aufruf ausgeblendet. Um die Fehlerzustände zu behandeln, werden Sie in schauen müssen $.ajax
, was komplexer ist , als $.load
, $.get
und dergleichen, aber viel flexibler zu.
showLoadingImage
Sie einfach an, bevor Sie beginnen und hideLoadingImage
nachdem Sie fertig sind. Sollte ziemlich einfach sein. Möglicherweise müssen Sie einen setTimeout
Anruf tätigen, um sicherzustellen, dass der Browser das neue <img>
Tag tatsächlich rendert. Ich habe einige Fälle gesehen, in denen es nicht stört, bis das JavaScript vollständig ausgeführt wurde.
Jonathons hervorragende Lösung bricht in IE8 ab (die Animation wird überhaupt nicht angezeigt). Um dies zu beheben, ändern Sie das CSS in:
.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)};
jQuery bietet Ereignis-Hooks für den Beginn und das Ende von AJAX-Anforderungen. Sie können sich in diese einhaken, um Ihren Lader anzuzeigen.
Erstellen Sie beispielsweise das folgende div:
<div id="spinner">
<img src="images/spinner.gif" alt="Loading" />
</div>
Stellen Sie es display: none
in Ihren Stylesheets ein. Sie können es so stylen, wie Sie möchten. Wenn Sie möchten, können Sie unter Ajaxload.info ein schönes Ladebild erstellen .
Anschließend können Sie Folgendes verwenden, damit es beim Senden von Ajax-Anforderungen automatisch angezeigt wird:
$(document).ready(function () {
$('#spinner').bind("ajaxSend", function() {
$(this).show();
}).bind("ajaxComplete", function() {
$(this).hide();
});
});
Fügen Sie diesen Javascript-Block einfach am Ende Ihrer Seite hinzu, bevor Sie Ihr Body-Tag schließen oder wo immer Sie es für richtig halten.
Wenn Sie jetzt Ajax-Anfragen senden, wird das #spinner
div angezeigt. Wenn die Anfrage abgeschlossen ist, wird sie wieder ausgeblendet.
Wenn Sie Turbolinks mit Schienen verwenden, ist dies meine Lösung:
Dies ist das CoffeeScript
$(window).on 'page:fetch', ->
$('body').append("<div class='modal'></div>")
$('body').addClass("loading")
$(window).on 'page:change', ->
$('body').removeClass("loading")
Dies ist das SASS CSS, das auf der ersten hervorragenden Antwort von Jonathan Sampson basiert
# 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;
}
Wie Mark H sagte, ist die blockUI der Weg.
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.: Ich habe das ajax-loader.gif auf http://www.ajaxload.info/
Bei allem Respekt vor anderen Posts haben Sie hier eine sehr einfache Lösung mit CSS3 und jQuery, ohne weitere externe Ressourcen oder Dateien zu verwenden.
$('#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" />
Dies würde die Schaltflächen verschwinden lassen, dann würde eine Animation des "Ladens" an ihrer Stelle erscheinen und schließlich nur eine Erfolgsmeldung anzeigen.
$(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>');
});
}
);
});
});
Die meisten Lösungen, die ich gesehen habe, erwarten entweder, dass wir ein Lade-Overlay entwerfen, es ausgeblendet und dann bei Bedarf wieder einblenden oder ein GIF oder Bild usw. anzeigen.
Ich wollte ein robustes Plugin entwickeln, mit dem ich mit einem einfachen jQuery-Aufruf den Ladebildschirm anzeigen und abreißen kann, wenn die Aufgabe abgeschlossen ist.
Unten ist der Code. Es hängt von Font awesome und jQuery ab:
/**
* 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));
Fügen Sie das Obige einfach in eine js-Datei ein und fügen Sie es in das gesamte Projekt ein.
CSS-Zusatz:
#custom-loading-overlay {
position: absolute;
left: 0;
top: 0;
bottom: 0;
right: 0;
background: #000;
opacity: 0.8;
filter: alpha(opacity=80);
}
#custom-loading {
width: 50px;
height: 57px;
position: absolute;
top: 50%;
left: 50%;
margin: -28px 0 0 -25px;
}
Aufruf:
$.loadingSpinner();
$.removeLoadingSpinner();
Beachten Sie, dass bei Verwendung von ASP.Net MVC mit das using (Ajax.BeginForm(...
Festlegen von ajaxStart
nicht funktioniert.
Verwenden Sie die AjaxOptions
, um dieses Problem zu beheben:
(Ajax.BeginForm("ActionName", new AjaxOptions { OnBegin = "uiOfProccessingAjaxAction", OnComplete = "uiOfProccessingAjaxActionComplete" }))
Laut https://www.w3schools.com/howto/howto_css_loader.asp ist dies ein zweistufiger Prozess ohne JS:
1. Fügen Sie diesen HTML-Code hinzu, wo Sie den Spinner haben möchten: <div class="loader"></div>
2. Fügen Sie dieses CSS hinzu, um den eigentlichen Spinner zu erstellen:
.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); }
}
$("#loader").toggle();
bevor sie die lang laufende Anforderung zum Starten der Animation stellen und in der Rückruffunktion der Anforderung einen weiteren Aufruf tätigen, um sie auszublenden.
Ich benutze CSS3 für die 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>