Wie kann ich mit jQuery eine Animation "Bitte warten, laden ..." erstellen?

585

Ich möchte eine Spinning-Circle-Animation "Bitte warten, laden" auf meiner Website platzieren. Wie soll ich das mit jQuery erreichen?

thedp
quelle

Antworten:

1211

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.

Die Einrichtung

Beginnen wir mit einer netten "Lade" -Animation von http://ajaxload.info, die ich verwenden werdeGeben Sie hier die Bildbeschreibung ein

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>

Das CSS

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

Und schließlich die jQuery

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 ajaxStartoder ajaxStopEreignisse 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/

Sampson
quelle
8
Dies ist die ausführlichste Lösung, obwohl ich empfehlen würde, ein Zentrierungs-Plugin zu verwenden, das den Preloader um ein Seitenelement ( dh body, #element oder .element ) zentriert
Corey Ballou
2
Das wäre eine schöne Ergänzung, Cballou. Ich habe lediglich versucht, die Informationen so gering wie möglich zu halten - aber wie Sie hervorheben, können sie sicherlich verbessert werden.
Sampson
9
Ich musste .bind () anstelle von .on () verwenden, da wir jQuery 1.5.1 verwenden!
RenegadeMind
37
Ich würde empfehlen, das Plugin zu verwenden, das Plugins zu den Plugins enthält, um sicherzustellen, dass alle angeschlossen sind.
contactmatt
15
Hinweis: Ab jQuery 1.8 sollte die Methode .ajaxStop()und .ajaxStart()nur noch an das Dokument angehängt werden. docs
balexandre
215

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;
});
Paolo Bergantino
quelle
4
Beachten Sie Folgendes: Wenn Sie den HTML-Code nicht ändern können, um das Lade-IMG-Element hinzuzufügen, können Sie dies als Hintergrundbild auf der Schaltfläche mithilfe von CSS ausführen, z. B. input.loading-gif {background: url ('images / load.gif'). ;} und wende dann die Klasse mit jQuery an, zB $ ('# mybutton'). addClass ('load-gif'); Das einzige Problem ist, dass das GIF nur angefordert wird, wenn auf die Schaltfläche "Senden" geklickt wird. Dies ist normalerweise zu spät. Sie müssen es also vorab zwischenspeichern, was mit jQuery einfach ist, z. B. (neues Bild ()). Src = "images /loading.gif ";
Jackocnr
4
Diese Seite hat eine größere und meiner Meinung nach schönere Auswahl an Ladern mit mehr Anpassungsoptionen. Preloaders.net
rorypicko
Zu Ihrer
Information
Schöne Lösung, aber wenn ich show () nach hide () aufrufe, funktioniert es nicht . Ich habe eine Lösung gefunden, die show show () und hide () umschaltet (). Ich hoffe, es kann jemandem helfen, das gleiche Problem wie ich zu haben. Außerdem habe ich Lösung C) ausprobiert und vorSend gegründet, dass es nicht asynchron funktioniert. Also schlug ich vor, show () über $ .ajax aufzurufen, um korrekt zu funktionieren.
16 瑲
Vielen Dank @Paolo. Persönlich hat mir Ihre Antwort besser gefallen als die, die von den meisten Benutzern akzeptiert wurde. Daher +1 an Sie von meiner Seite.
Ashok Kumar
113

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 ajaxStartVeranstaltung

Zeigen Sie eine Lademeldung an, wenn eine AJAX-Anforderung gestartet wird (und keine bereits aktiv ist).

... und es ist Bruder, das ajaxStopEreignis

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();
 });
Dan F.
quelle
Dies ist veraltet, ab 1.8.0 .ajaxStartkann nur an Dokument angehängt werden, dh. $(document).ajaxStart(function(){}).
Jonno_FTW
2
@Jonno_FTW behoben. Ta. Alte Frage und Antwort, die durch Jonathan Sampsons Änderungen an seiner Frage ersetzt wurde, aber gut, um sie trotzdem auf dem neuesten Stand zu halten
Dan F
3
Jonathans Antwort war sehr ausführlich, aber das war für mich das Beste für seine Einfachheit.
Ojonugwa Jude Ochalifu
19

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, $.getund dergleichen, aber viel flexibler zu.

Samir Talwar
quelle
2
Danke für die Antwort. Aber sag mir, warum muss ich AJAX überhaupt verwenden? Kann ich nicht einfach alles auf der Seite selbst finden?
Der
Was genau möchten Sie verfolgen? Wenn Sie nach dem Laden der Seite keine Informationen anfordern (und AJAX ist so ziemlich die einzige Möglichkeit, dies ohne Verwendung eines Plugins zu tun), warum sollten Sie überhaupt ein Bild zum "Laden" benötigen?
Samir Talwar
Samir Talwar: Eigentlich eine schwere JavaScript-Anwendung. Danke, ich habe die Idee.
Der
Verständlich. In diesem Fall rufen showLoadingImageSie einfach an, bevor Sie beginnen und hideLoadingImagenachdem Sie fertig sind. Sollte ziemlich einfach sein. Möglicherweise müssen Sie einen setTimeoutAnruf 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.
Samir Talwar
16

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)};
Ben Power
quelle
2
Bearbeitet, weil die mehreren 'Hintergrund-' Zeilen nicht funktionierten, aber die einzelne Hintergrundanweisung korrekt funktioniert.
Maurice Flanagan
7

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: nonein 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 #spinnerdiv angezeigt. Wenn die Anfrage abgeschlossen ist, wird sie wieder ausgeblendet.

Veeti
quelle
Kann jemand bitte erklären, was AJAX damit zu tun hat? Kann ich das nicht einfach auf der Seite verwalten, ohne mit AJAX auf den Server zuzugreifen? Oder fehlt mir hier etwas? Vielen Dank.
Der
4
Ah - wie ich verstanden habe, wollten Sie, dass ein Ladebild angezeigt wird, wenn Sie AJAX-Anfragen stellen. Wenn Sie einfach möchten, dass eine Animation "Bitte warten, Laden ..." angezeigt wird, bis die Seite vollständig geladen ist, können Sie ein Ladediv auf der Seite haben und es dann in Ihrem $ (Dokument) .ready-Block ausblenden.
Veeti
7

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;
}
Fred
quelle
6

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/

bpedroso
quelle
Zu Ihrer
Information
6

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

João Pimentel Ferreira
quelle
5

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>');
                    });
                }
        );
    });
});
Tsundoku
quelle
Zu Ihrer
Information
5

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();
Raj Pawan Gumdal
quelle
4

Beachten Sie, dass bei Verwendung von ASP.Net MVC mit das using (Ajax.BeginForm(...Festlegen von ajaxStartnicht funktioniert.

Verwenden Sie die AjaxOptions, um dieses Problem zu beheben:

(Ajax.BeginForm("ActionName", new AjaxOptions { OnBegin = "uiOfProccessingAjaxAction", OnComplete = "uiOfProccessingAjaxActionComplete" }))
Rami Weiss
quelle
Zu Ihrer
Information
2

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); }
}
hamx0r
quelle
Da das OP jQuery verwendet, können sie aufrufen, $("#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.
Dmitri Chubarov
2

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>

Camille
quelle