#javascript #jquery #html
#javascript #jquery #HTML
Вопрос:
У меня есть следующий пример, который использует события выполнения в XHR2 для отображения индикатора выполнения пользователю при выполнении запроса AJAX:
$.ajax({
xhr: function() {
var xhr = new window.XMLHttpRequest();
xhr.upload.addEventListener('progress', function(evt){
if (evt.lengthComputable) {
var percentComplete = (evt.loaded / evt.total) * 100;
if(percentComplete >= 100){
$('#loading-bar').find('.bar').css({'width': percentComplete '%'});
$('#loading-bar')
.find('.bar')
.on('transitionend webkitTransitionEnd oTransitionEnd otransitionend MSTransitionEnd', function() {
$('#loading-bar').fadeOut(function(){
$('#loading-bar').find('.bar').css({'width': ''});
});
});
} else {
$('#loading-bar').find('.bar').css({'width': percentComplete '%'});
}
}
}, false);
return xhr;
},
type: 'GET',
url: 'Test.html',
success: function (response) {
},
error: function (jqXHR, textStatus, errorThrown) {
}
});
Однако для браузеров, которые не поддерживают XHR2, панель не будет анимироваться, и элемент loading-bar не будет удален из DOM.
Как я могу реализовать резервный вариант? Поскольку я не хочу просто отключать панель загрузки при успешном завершении, поскольку это приведет к конфликту с событиями выполнения для браузеров, которые его поддерживают.
Или, что еще лучше, возможно ли получить прогресс альтернативными средствами?
Комментарии:
1. Некоторые браузеры, которые не реализуют progress api, все равно позволят вам получить доступ к заголовку
.response.length
иcontent-length
заголовку после получения заголовков. Для загрузки вам не повезло, afaik.2. Почему бы не проверить в вашей функции успеха, поддерживается ли xhr2, а если нет, то только исчезает.
3. @Bergi Я не думаю, что меня волнует ход загрузки… просто загрузка, которую я показываю в своем вопросе. У вас есть несколько примеров того, как я могу использовать альтернативные API. Спасибо.
4. Извините, если я неправильно понимаю ситуацию, но это могло бы
.readyState
помочь? Возможно, вы могли бы упростить панель загрузки для XHR, используя.readyState
.5. @NobleMushtak Пожалуйста, не стесняйтесь показывать пример. Спасибо.
Ответ №1:
Если это прогресс загрузки, мы можем сделать это, когда xhr.readyState >= 3
. Просто прочитайте xhr.responseText.length
, а затем разделите его на parseInt(xhr.getResponseHeader('Content-Length'))
(при условии, что сервер предоставляет этот заголовок, и он того же происхождения или с правильным заголовком CORS).
Если это прогресс загрузки, я не знаю ни одного способа его полизаполнения исключительно на стороне клиента. Мы можем создать идентификатор для каждого сеанса загрузки и использовать другой xhr
для получения прогресса получения загрузки с сервера. Однако это требует сложной реализации на стороне сервера. Существует много таких реализаций на распространенных языках, например, для PHP или .NET. Вы можете изучить их и реализовать свои собственные.
Комментарии:
1. Интересует только ход загрузки. Не могли бы вы показать простой пример того, как я могу обновить ширину индикатора выполнения на основе вашего решения? Спасибо.
2. @Cameron:
xhr.onreadystatechange = function() { if (xhr.readyState >= 3) { var progress = xhr.responseText.length / parseInt(xhr.getResponseHeader('Content-Length')); } };
3. Вы должны указать это в своем ответе, а затем я проведу тест.
Ответ №2:
Попробуйте использовать .onreadystatechange()
с .readyState
:
getter.onreadystatechange = function() {
if (loading) { //If the loading element has been loaded...
if (this.status === 200) { //If this.status is already 200...
loading.style.width = this.readyState*25 "%"; //This sets the width of loading according to this.readyState
if (this.readyState === 4) {
//We hide loadingBar and do stuff when we're done.
loadingBar.style.display = "none";
[do stuff]
}
}
}
};
Если вы принимаете 100 Continue
статусы, вы также можете указать это в панели загрузки. То, как это происходит сейчас, на некоторое время останавливается, но затем масштабируется до 100%, когда он переходит к статусу 200 OK
, и readyState
свойство переходит от 2
к 4
.
Вот в чем проблема: http://jsfiddle.net/NobleMushtak/QRuU6 /