Bagaimana saya bisa membuat animasi "Mohon Tunggu, Memuat ..." menggunakan jQuery?

585

Saya ingin menempatkan animasi lingkaran pemintalan "harap tunggu, memuat" di situs saya. Bagaimana saya melakukannya dengan jQuery?

terima kasih
sumber

Jawaban:

1211

Anda dapat melakukan ini dengan berbagai cara berbeda. Ini bisa berupa status kecil pada halaman yang mengatakan "Memuat ...", atau sekeras elemen yang memutih halaman saat data baru dimuat. Pendekatan yang saya ambil di bawah ini akan menunjukkan kepada Anda bagaimana menyelesaikan kedua metode.

Pengaturan

Mari kita mulai dengan memberi kita animasi "memuat" yang bagus dari http://ajaxload.info yang akan saya gunakanmasukkan deskripsi gambar di sini

Mari kita buat elemen yang bisa kita tampilkan / sembunyikan kapan saja kita membuat permintaan ajax:

<div class="modal"><!-- Place at bottom of page --></div>

CSS

Selanjutnya mari kita berikan bakat:

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

Dan akhirnya, jQuery

Baiklah, ke jQuery. Bagian selanjutnya ini sebenarnya sangat sederhana:

$body = $("body");

$(document).on({
    ajaxStart: function() { $body.addClass("loading");    },
     ajaxStop: function() { $body.removeClass("loading"); }    
});

Itu dia! Kami melampirkan beberapa acara ke elemen tubuh kapan saja ajaxStartatau ajaxStopacara dipecat. Ketika acara ajax dimulai, kami menambahkan kelas "memuat" ke tubuh. dan ketika acara selesai, kami menghapus kelas "memuat" dari tubuh.

Lihat dalam aksi: http://jsfiddle.net/VpDUG/4952/

Sampson
sumber
8
Ini adalah yang paling dalam larutan mendalam meskipun saya akan merekomendasikan Anda menggunakan plugin berpusat yang berpusat pada preloader sekitar elemen halaman ( yaitu tubuh, #element, atau .element )
Corey Ballou
2
Itu akan menjadi tambahan yang bagus, cballou. Saya hanya berusaha untuk meminimalkan informasi - tetapi seperti yang Anda tunjukkan, tentu saja dapat ditingkatkan.
Sampson
9
Saya harus menggunakan .bind () bukannya .on () karena kami menggunakan jQuery 1.5.1!
renegadeMind
38
Saya akan merekomendasikan menggunakan plugin yang plugins ke plugins untuk memastikan semuanya terpasang.
contactmatt
15
Catatan: Pada jQuery 1.8, metode .ajaxStop()dan .ajaxStart()hanya boleh dilampirkan ke dokumen. docs
balexandre
215

Sejauh memuat gambar yang sebenarnya, periksa situs ini untuk banyak pilihan.

Sejauh menampilkan DIV dengan gambar ini saat permintaan dimulai, Anda memiliki beberapa pilihan:

A) Perlihatkan dan sembunyikan gambar secara manual:

$('#form').submit(function() {
    $('#wait').show();
    $.post('/whatever.php', function() {
        $('#wait').hide();
    });
    return false;
});

B) Gunakan ajaxStart dan ajaxComplete :

$('#wait').ajaxStart(function() {
    $(this).show();
}).ajaxComplete(function() {
    $(this).hide();
});

Menggunakan ini elemen akan menampilkan / menyembunyikan permintaan apa pun . Bisa baik atau buruk, tergantung kebutuhan.

C) Gunakan panggilan balik individual untuk permintaan tertentu:

$('#form').submit(function() {
    $.ajax({
        url: '/whatever.php',
        beforeSend: function() { $('#wait').show(); },
        complete: function() { $('#wait').hide(); }
    });
    return false;
});
Paolo Bergantino
sumber
4
Sesuatu yang perlu diperhatikan: jika Anda tidak dapat memodifikasi HTML untuk menambahkan elemen img pemuatan, Anda dapat melakukannya sebagai gambar latar belakang pada tombol menggunakan CSS misalnya input.loading-gif {background: url ('images / loading.gif') ;} dan kemudian terapkan kelas dengan jQuery misalnya $ ('# mybutton'). addClass ('loading-gif'); Satu-satunya gotcha adalah ini hanya akan meminta gif ketika tombol kirim diklik, yang biasanya terlambat, jadi Anda perlu melakukan pra-cache, yang mudah dengan jQuery misalnya (Gambar baru ()). Src = "gambar /loading.gif ";
jackocnr
4
Situs ini memiliki pilihan loader yang lebih besar dan menurut saya lebih bagus dengan lebih banyak opsi penyesuaian preloaders.net
rorypicko
FYI: digabung dari stackoverflow.com/questions/750358/…
Shog9
Solusi yang bagus, tetapi ketika saya memanggil show () setelah hide () itu tidak berfungsi . Saya menemukan solusi yang beralih show () dan hide () untuk beralih (). Berharap itu dapat membantu seseorang memiliki masalah yang sama dengan saya. Juga, saya mencoba solusi C) dan didirikan sebelumKirim tidak bekerja di async. Jadi, saya menyarankan untuk memanggil show () di atas $ .ajax agar berfungsi dengan benar.
劉鎮 瑲
@Paolo terima kasih banyak. Secara pribadi, saya menyukai jawaban Anda daripada jawaban yang diterima oleh sebagian besar pengguna. Karenanya, +1 untuk Anda dari sisi saya.
Ashok kumar
113

Bersamaan dengan apa yang disarankan Jonathan dan Samir (keduanya jawaban yang bagus sekali!), JQuery memiliki beberapa kejadian yang akan muncul untuk Anda saat membuat permintaan ajax.

Ada ajaxStartacara

Tampilkan pesan pemuatan setiap kali permintaan AJAX dimulai (dan belum ada yang aktif).

... dan itu saudara, ajaxStopacara itu

Lampirkan fungsi yang akan dieksekusi setiap kali semua permintaan AJAX telah berakhir. Ini adalah Acara Ajax.

Bersama-sama, mereka membuat cara yang baik untuk menampilkan pesan kemajuan ketika aktivitas ajax terjadi di mana saja di halaman.

HTML:

<div id="loading">
  <p><img src="loading.gif" /> Please Wait</p>
</div>

Naskah:

$(document).ajaxStart(function(){
    $('#loading').show();
 }).ajaxStop(function(){
    $('#loading').hide();
 });
Dan F
sumber
Ini sudah usang, pada 1.8.0, .ajaxStarthanya bisa dilampirkan ke dokumen, yaitu. $(document).ajaxStart(function(){}).
Jonno_FTW
2
@Jonno_FTW diperbaiki. Ta. Pertanyaan dan jawaban lama yang telah diawasi oleh suntingan Jonathan Sampson untuk pertanyaannya, tetapi tetap baik untuk tetap up to date
Dan F
3
Jawaban Jonathan sangat dalam, tetapi bagi saya ini yang terbaik karena kesederhanaannya.
Ojonugwa Jude Ochalifu
19

Anda dapat mengambil GIF animasi dari lingkaran pemintalan dari Ajaxload - tempelkan di suatu tempat dalam hirarki file situs web Anda. Maka Anda hanya perlu menambahkan elemen HTML dengan kode yang benar, dan menghapusnya setelah selesai. Ini cukup sederhana:

function showLoadingImage() {
    $('#yourParentElement').append('<div id="loading-image"><img src="path/to/loading.gif" alt="Loading..." /></div>');
}

function hideLoadingImage() {
    $('#loading-image').remove();
}

Maka Anda hanya perlu menggunakan metode ini dalam panggilan AJAX Anda:

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

Ini memiliki beberapa peringatan: pertama-tama, jika Anda memiliki dua atau lebih tempat gambar pemuatan dapat ditampilkan, Anda perlu melacak berapa banyak panggilan yang berjalan sekaligus, dan hanya menyembunyikan ketika mereka semua selesai. Ini dapat dilakukan dengan menggunakan penghitung sederhana, yang harus bekerja untuk hampir semua kasus.

Kedua, ini hanya akan menyembunyikan gambar pemuatan pada panggilan AJAX yang berhasil. Untuk menangani status kesalahan, Anda harus melihat ke dalam $.ajax, yang lebih kompleks daripada $.load, $.getdan sejenisnya, tetapi juga jauh lebih fleksibel.

Samir Talwar
sumber
2
Terima kasih balasannya. Tetapi katakan padaku, mengapa saya harus menggunakan AJAX sama sekali? Tidak bisakah saya melacak semuanya di halaman itu sendiri?
thedp
Apa sebenarnya yang ingin Anda lacak? Kecuali jika Anda meminta informasi setelah halaman dimuat (dan AJAX adalah satu-satunya cara untuk melakukannya tanpa menggunakan plugin), mengapa Anda memerlukan gambar "memuat" sama sekali?
Samir Talwar
Samir Talwar: Aplikasi JavaScript yang berat sebenarnya. Terima kasih, saya mengerti.
thedp
Bisa dimengerti Dalam hal ini, panggil saja showLoadingImagesebelum Anda mulai dan hideLoadingImagesetelah Anda selesai. Seharusnya cukup sederhana. Anda mungkin perlu memasukkan semacam setTimeoutpanggilan untuk memastikan browser benar-benar membuat <img>tag baru - Saya telah melihat beberapa kasus di mana tidak mengganggu sampai JavaScript selesai dieksekusi.
Samir Talwar
16

Solusi terbaik Jonathon di IE8 (animasi tidak ditampilkan sama sekali). Untuk memperbaiki ini, ubah CSS ke:

.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
sumber
2
Diedit karena beberapa baris 'latar belakang-' tidak berfungsi, tetapi pernyataan latar belakang tunggal berfungsi dengan benar.
Maurice Flanagan
7

jQuery menyediakan kait acara untuk saat AJAX meminta mulai dan berakhir. Anda dapat menghubungkan ini untuk menunjukkan loader Anda.

Misalnya, buat div berikut:

<div id="spinner">
  <img src="images/spinner.gif" alt="Loading" />
</div>

Atur ke display: nonedalam stylesheet Anda. Anda dapat mengaturnya dengan cara apa pun yang Anda inginkan. Anda dapat menghasilkan gambar pemuatan yang bagus di Ajaxload.info , jika Anda mau.

Kemudian, Anda dapat menggunakan sesuatu seperti berikut untuk membuatnya ditampilkan secara otomatis saat mengirim permintaan Ajax:

$(document).ready(function () {

    $('#spinner').bind("ajaxSend", function() {
        $(this).show();
    }).bind("ajaxComplete", function() {
        $(this).hide();
    });

});

Cukup tambahkan blok Javascript ini ke akhir halaman Anda sebelum menutup tag tubuh Anda atau di mana pun Anda mau.

Sekarang, setiap kali Anda mengirim permintaan Ajax, #spinnerdiv akan ditampilkan. Ketika permintaan selesai, itu akan disembunyikan lagi.

Veeti
sumber
Bisakah seseorang menjelaskan apa yang harus dilakukan AJAX dengan ini? Tidak bisakah saya mengatur semua ini di dalam halaman tanpa mengakses server dengan AJAX ... Atau saya kehilangan sesuatu di sini? Terima kasih.
thedp
4
Ah - seperti yang saya mengerti, Anda ingin memuat gambar untuk ditampilkan setiap kali Anda membuat permintaan AJAX. Jika Anda hanya ingin animasi "harap tunggu, memuat ..." untuk ditampilkan sampai halaman telah dimuat penuh, Anda dapat memiliki div pemuatan di halaman dan kemudian menyembunyikannya di $ (dokumen) Anda. Sudah blokir.
Veeti
7

Jika Anda menggunakan Turbolinks With Rails, ini solusi saya:

Ini adalah CoffeeScript

$(window).on 'page:fetch', ->
  $('body').append("<div class='modal'></div>")
  $('body').addClass("loading")

$(window).on 'page:change', ->
  $('body').removeClass("loading")

Ini adalah SASS CSS berdasarkan pada jawaban bagus pertama dari Jonathan Sampson

# 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
sumber
6

Seperti Mark H katakan, blockUI adalah caranya.

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 .: Saya mendapat ajax-loader.gif di http://www.ajaxload.info/

bpedroso
sumber
FYI: digabung dari stackoverflow.com/questions/750358/…
Shog9
6

Dengan segala hormat terhadap posting lain, Anda memiliki solusi yang sangat sederhana di sini, menggunakan CSS3 dan jQuery, tanpa menggunakan sumber daya eksternal lebih lanjut atau file.

$('#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
sumber
5

Ini akan membuat tombol-tombol menghilang, maka animasi "memuat" akan muncul di tempatnya dan akhirnya hanya menampilkan pesan yang berhasil.

$(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
sumber
FYI: digabung dari stackoverflow.com/questions/750358/…
Shog9
5

Sebagian besar solusi yang saya lihat mengharapkan kita untuk merancang overlay pemuatan, menyembunyikannya dan kemudian menyembunyikannya saat diperlukan, atau, menampilkan gif atau gambar, dll.

Saya ingin mengembangkan plugin yang kuat, di mana dengan panggilan jQuery sederhana saya dapat menampilkan layar memuat dan merobohkannya ketika tugas selesai.

Di bawah ini adalah kode. Itu tergantung pada Font yang mengagumkan dan jQuery:

/**
 * 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)); 

Masukkan saja di atas dalam file js dan sertakan di seluruh proyek.

Penambahan CSS:

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

Doa:

$.loadingSpinner();
$.removeLoadingSpinner();
Raj Pawan Gumdal
sumber
4

Perhatikan bahwa saat menggunakan ASP.Net MVC, dengan using (Ajax.BeginForm(..., pengaturan ajaxStarttidak akan berfungsi.

Gunakan AjaxOptionsuntuk mengatasi masalah ini:

(Ajax.BeginForm("ActionName", new AjaxOptions { OnBegin = "uiOfProccessingAjaxAction", OnComplete = "uiOfProccessingAjaxActionComplete" }))
Rami Weiss
sumber
FYI: digabung dari stackoverflow.com/questions/750358/…
Shog9
2

Per https://www.w3schools.com/howto/howto_css_loader.asp , ini adalah proses 2 langkah tanpa JS:

1.Tambahkan HTML ini di tempat yang Anda inginkan pemintal: <div class="loader"></div>

2. Tambahkan CSS ini untuk membuat pemintal yang sebenarnya:

.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
sumber
Karena OP menggunakan jQuery, mereka dapat menelepon $("#loader").toggle();sebelum membuat permintaan yang berjalan lama untuk memulai animasi dan membuat panggilan lain dalam fungsi panggilan balik dari permintaan untuk menyembunyikannya.
Dmitri Chubarov
2

Saya menggunakan CSS3 untuk animasi

/************ 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
sumber