Відповіді:
Ви могли це зробити різними способами. Це може бути тонким, як невеликий статус на сторінці з написом "Завантаження ...", або ж голосний, як цілий елемент, що переносить сторінку, коли нові дані завантажуються. Підхід, який я застосовую нижче, покаже вам, як досягти обох методів.
Почнемо з того, щоб отримати нам приємну "завантажувальну" анімацію з http://ajaxload.info, яку я буду використовувати
Давайте створимо елемент, який ми можемо показати / приховати будь-коли, коли ми робимо запит на ajax:
<div class="modal"><!-- Place at bottom of page --></div>
Далі давайте трохи почуття:
/* 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. Наступна частина насправді дуже проста:
$body = $("body");
$(document).on({
ajaxStart: function() { $body.addClass("loading"); },
ajaxStop: function() { $body.removeClass("loading"); }
});
Це воно! Ми приєднуємо деякі події до елемента тіла в будь-який час, ajaxStart
або ajaxStop
події запускаються. Коли починається подія "Аякс", ми додаємо до тіла клас "завантаження". і коли події виконані, ми видаляємо клас "завантаження" з тіла.
Дивіться це в дії: http://jsfiddle.net/VpDUG/4952/
.ajaxStop()
і .ajaxStart()
метод слід додавати лише до документа. docs
Що стосується фактичного завантаження зображення, перегляньте на цьому сайті купу варіантів.
Що стосується відображення 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;
});
Поряд із тим, що запропонували Джонатан та Самір (обидва відмінні відповіді btw!), JQuery має деякі вбудовані події, які він запустить для вас під час запиту на ajax.
Там ajaxStart
подія
Показуйте повідомлення про завантаження кожного разу, коли починається запит AJAX (і жодне вже не активне).
... і це брат, ajaxStop
подія
Приєднайте функцію, яка виконується щоразу, коли всі запити AJAX закінчуються. Це подія Ajax.
Разом вони створюють чудовий спосіб відобразити повідомлення про хід роботи, коли будь-яка діяльність у програмі Ajax відбувається де-небудь на сторінці.
HTML:
<div id="loading">
<p><img src="loading.gif" /> Please Wait</p>
</div>
Сценарій:
$(document).ajaxStart(function(){
$('#loading').show();
}).ajaxStop(function(){
$('#loading').hide();
});
.ajaxStart
може бути додане лише до документа, тобто. $(document).ajaxStart(function(){}).
Ви можете захопити анімований 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
тощо, але набагато більш гнучким теж.
showLoadingImage
перед тим, як почати і hideLoadingImage
після того, як закінчите. Повинен бути досить простим. Можливо, вам доведеться ввести якийсь setTimeout
виклик, щоб переконатися, що браузер фактично видає новий <img>
тег - я бачив кілька випадків, коли він не турбує, поки JavaScript не закінчить виконання.
Чудове рішення Джонатана перерва в 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)};
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, #spinner
буде показано div. Коли запит буде завершено, він буде знову прихований.
Якщо ви використовуєте 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;
}
Як Марк Н сказав, що блокUI - це шлях.
Наприклад:
<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/
При всій повазі до інших публікацій, у вас тут дуже просте рішення, використовуючи 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" />
Це призвело б до зникнення кнопок, тоді на їх місці з’явиться анімація «завантаження» і нарешті просто відобразиться повідомлення про успіх.
$(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>');
});
}
);
});
});
Більшість рішень, які я бачив, або очікує, що ми створимо накладку для завантаження, збережемо її прихованою, а потім приховаємо, коли потрібно, або покажемо gif або зображення тощо.
Я хотів розробити надійний плагін, де за допомогою просто дзвінка jQuery я можу відобразити екран завантаження і зруйнувати його, коли завдання буде виконано.
Нижче - код. Це залежить від дивовижного шрифту та 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-файл і включіть його в проект.
Додавання 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;
}
Виклик:
$.loadingSpinner();
$.removeLoadingSpinner();
Зауважте, що при використанні ASP.Net MVC, з using (Ajax.BeginForm(...
, встановленнямajaxStart
не буде працювати.
Використовуйте AjaxOptions
для подолання цього питання:
(Ajax.BeginForm("ActionName", new AjaxOptions { OnBegin = "uiOfProccessingAjaxAction", OnComplete = "uiOfProccessingAjaxActionComplete" }))
На 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); }
}
$("#loader").toggle();
перед тим, як зробити тривалий запит, щоб запустити анімацію та здійснити ще один виклик у функції зворотного дзвінка запиту, щоб приховати її.
Я використовую 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>