Как создать анимацию «Пожалуйста, подождите, идет загрузка…» с помощью jQuery?

529

Я хотел бы разместить на моем сайте анимацию кругового кругового движения "Подождите, загрузите". Как это сделать с помощью jQuery?

  • 2
    Рассмотрим PNG с преобразованиями CSS, а не GIF.
  • 6
    @WTP Что не так с GIF-файлами?
Показать ещё 1 комментарий
Теги:
animation

14 ответов

1067
Лучший ответ

Вы можете сделать это различными способами. Это может быть тонким, как небольшой статус на странице с надписью "Загрузка..." или громким, как весь элемент, выделяющий страницу во время загрузки новых данных. Подход, который я принимаю ниже, покажет вам, как выполнить оба метода.

Настройка

Давайте начнем с получения приятной анимации "загрузки" из http://ajaxload.info Я буду использовать Изображение 2255

Позвольте создать элемент, который мы можем показать/скрыть в любое время, когда мы делаем запрос ajax:

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

CSS

Затем дайте ему некоторое чутье:

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

И, наконец, jQuery

Хорошо, на jQuery. Эта следующая часть на самом деле очень проста:

$body = $("body");

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

Что это! Мы присоединяем некоторые события к элементу body в любое время при запуске событий ajaxStart или ajaxStop. Когда начинается событие ajax, мы добавляем класс "loading" к телу. и когда события будут выполнены, мы удалим класс загрузки с тела.

Смотрите в действии: http://jsfiddle.net/VpDUG/4952/

  • 6
    Это наиболее глубокое решение, хотя я бы порекомендовал вам использовать центрирующий плагин, который центрирует предварительный загрузчик вокруг элемента страницы ( т.е. body, #element или .element )
  • 1
    Это было бы хорошим дополнением, cballou. Я просто пытался свести информацию к минимуму, но, как вы указываете, ее можно улучшить.
Показать ещё 21 комментарий
204

Что касается фактического загружаемого изображения, проверить этот сайт для кучи опций.

Что касается отображения DIV с этим изображением при начале запроса, у вас есть несколько вариантов:

A) Вручную покажите и спрячьте изображение:

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

B) Используйте ajaxStart и ajaxComplete:

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

С помощью этого элемента будет отображаться/скрываться для любого запроса. Может быть хорошим или плохим, в зависимости от необходимости.

C) Используйте отдельные обратные вызовы для конкретного запроса:

$('#form').submit(function() {
    $.ajax({
        url: '/whatever.php',
        beforeSend: function() { $('#wait').show(); },
        complete: function() { $('#wait').hide(); }
    });
    return false;
});
  • 3
    На что следует обратить внимание: если вы не можете изменить HTML, чтобы добавить загрузочный элемент img, вы можете сделать это как фоновое изображение на кнопке с помощью CSS, например input.loading-gif {background: url ('images / loading.gif') ;} и затем примените класс с помощью jQuery, например, $ ('# mybutton'). addClass ('loading-gif'); Единственное, что нужно, это то, что это будет запрашивать GIF только при нажатии кнопки отправки, что обычно слишком поздно, поэтому вам нужно предварительно кэшировать его, что легко с jQuery, например (new Image ()). Src = "images /loading.gif ";
  • 3
    Этот сайт имеет более широкий и, на мой взгляд, более хороший выбор загрузчиков с более широкими возможностями настройки preloaders.net
Показать ещё 1 комментарий
108

Наряду с тем, что предложил Джонатан и Самир (оба отличных ответа кстати!), jQuery имеет некоторые встроенные события, которые будут срабатывать для вас при создании запроса ajax.

Здесь ajaxStart событие

Показывать загружаемое сообщение при запуске запроса AJAX (и ни один из них уже не активен).

... и это брат, ajaxStop событие

Прикрепите функцию, которая будет выполняться всякий раз, когда все запросы AJAX завершатся. Это событие Ajax.

Вместе они делают прекрасный способ показать сообщение о ходе, когда любая активность ajax происходит в любом месте страницы.

HTML:

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

Script:

$(document).ajaxStart(function(){
    $('#loading').show();
 }).ajaxStop(function(){
    $('#loading').hide();
 });
  • 0
    Это устаревшее, по состоянию на 1.8.0, .ajaxStart можно прикрепить только к документу, т.е. $(document).ajaxStart(function(){}).
  • 1
    @Jonno_FTW исправлено. Ta. Старый вопрос и ответ, который был заменен правками Джонатана Сэмпсона на его вопрос, но в любом случае хорошо, чтобы он был в курсе
Показать ещё 1 комментарий
17

Вы можете захватить анимированный GIF вращающегося круга из Ajaxload - придерживаться того, что где-то в вашей иерархии веб-сайта. Тогда вам просто нужно добавить элемент HTML с правильным кодом и удалить его, когда закончите. Это довольно просто:

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

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

Вам просто нужно использовать эти методы в своем вызове AJAX:

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

В этом есть несколько предостережений: во-первых, если у вас есть два или более места, изображение загрузки может отображаться, вам нужно будет отслеживать, сколько вызовов работает одновременно, и только скрывать, когда они все закончили. Это можно сделать с помощью простого счетчика, который должен работать практически во всех случаях.

Во-вторых, это только скроет загружаемое изображение при успешном вызове AJAX. Чтобы справиться с состояниями ошибки, вам нужно изучить $.ajax, что более сложно, чем $.load, $.get и например, но намного более гибким.

  • 1
    Спасибо за ответ. Но скажите, зачем мне вообще использовать AJAX? Разве я не могу просто отследить все это на самой странице?
  • 0
    Что именно вы хотите отслеживать? Если вы не запрашиваете информацию после загрузки страницы (а AJAX является практически единственным способом сделать это без использования плагина), зачем вам вообще нужно «загружать» изображение?
Показать ещё 2 комментария
14

Отличное решение Jonathon ломается в IE8 (анимация вообще не отображается). Чтобы исправить это, измените CSS на:

.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)};
  • 1
    Отредактировано, потому что несколько строк 'background-' не работали, но один оператор background работал правильно.
6

Если вы используете Turbolinks With Rails, это мое решение:

Это CoffeeScript

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

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

Это SASS CSS, основанный на первом отличном ответе Джонатана Сампсона

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

jQuery предоставляет привязки к событиям, когда AJAX запрашивает начало и конец. Вы можете подключиться к ним, чтобы показать свой загрузчик.

Например, создайте следующий div:

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

Установите значение display: none в таблице стилей. Вы можете стилизовать его так, как хотите. Вы можете создать хорошее загружаемое изображение на Ajaxload.info, если хотите.

Затем вы можете использовать что-то вроде следующего, чтобы оно отображалось автоматически при отправке запросов Ajax:

$(document).ready(function () {

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

});

Просто добавьте этот блок Javascript в конец своей страницы до, закрыв тег тела или где бы вы ни находились.

Теперь, когда вы отправляете запросы Ajax, будет показан div #spinner. Когда запрос будет завершен, он снова будет скрыт.

  • 0
    Может кто-нибудь объяснить, что AJAX имеет к этому отношение? Разве я не могу просто управлять всем этим на странице, не обращаясь к серверу с помощью AJAX ... Или я что-то здесь упускаю? Благодарю.
  • 3
    Ах, как я понял, вы хотели, чтобы изображение загрузки отображалось при каждом выполнении запросов AJAX. Если вы просто хотите, чтобы анимация «Пожалуйста, подождите, загружается ...» отображалась до тех пор, пока страница не загрузится полностью, вы можете создать загрузочный div на странице, а затем скрыть ее в своем блоке $ (document) .ready.
5

Как и Марк Х сказал, что blockUI - это способ.

Пример:.

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

Обь.: Я получил ajax-loader.gif на http://www.ajaxload.info/

4

При всем уважении к другим сообщениям у вас здесь очень простое решение, использующее CSS3 и jQuery, без использования каких-либо дополнительных внешних ресурсов и файлов.

$('#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" />
3

Большинство решений, которые я видел, либо ожидают, что мы разработаем накладку загрузки, сохраним ее, а затем отобразим, когда это потребуется, или покажите gif или изображение и т.д.

Я хотел создать надежный плагин, где с помощью простого вызова jQuery я могу отобразить экран загрузки и разорвать его, когда задача будет завершена.

Ниже приведен код. Это зависит от Font awesome и 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)); 

Просто поместите вышеуказанное в файл js и включите его во весь проект.

Призвание:

$.loadingSpinner();
$.removeLoadingSpinner();
3

обратите внимание, что при использовании asp.net mvc с "использованием (Ajax.BeginForm(..." настройка "ajaxStart" не будет работать.

используйте ajaxotions для устранения этой проблемы:

(Ajax.BeginForm("ActionName", new AjaxOptions { OnBegin = "uiOfProccessingAjaxAction", OnComplete = "uiOfProccessingAjaxActionComplete" }))
3

Это приведет к исчезновению кнопок, после чего на их месте появится анимация "загрузка" и, наконец, просто отобразит сообщение об успешном завершении.

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

Per https://www.w3schools.com/howto/howto_css_loader.asp, это двухэтапный процесс без JS:

1. Добавьте этот HTML-код, где вы хотите использовать счетчик: <div class="loader"></div>

2. Добавьте этот CSS, чтобы сделать фактический счетчик:

.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); }
}
  • 0
    Поскольку OP использует jQuery, они могут вызывать $("#loader").toggle(); перед выполнением длительного запроса, чтобы запустить анимацию и сделать еще один вызов в функции обратного вызова запроса, чтобы скрыть ее.
1

Я использую CSS3 для анимации

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню