Подтвердить что ты не робот

Показывать прогресс в процессе загрузки страниц с помощью jquery ajax на одном веб-сайте

У меня есть базовая страница с верхней панелью навигации и оболочкой.

Всякий раз, когда пользователь нажимает на ссылку навигации, он использует .load для загрузки содержимого страницы в обертку div.

$(this).ajaxStart(function(){$('.progressbar .bar').css('width','5%');$('.progressbar').fadeIn();});
$(this).ajaxEnd(function(){$('progressbar').hide();});

$('.ajaxspl').on('click',function(e){
    e.preventDefault();

    var url=$(this).data('url'),
        wrap=$('body #wrap');

    //clean the wrapper
    wrap.slideUp().html('');

    //load page into wrapper
    wrap.load(url,function(){wrap.slideDown();});
});

Пример возвращаемого значения из .load:

<div>
...content
</div>
<script>$('.progressbar .bar').css('width','30%');</script>
<link href="/assets/css/datepicker.css" rel="stylesheet" />
<script>$('.progressbar .bar').css('width','60%');</script>
<link href="/assets/css/main.css" rel="stylesheet" />
<script>$('.progressbar .bar').css('width','90%');</script>
<script>//blah blah</script>

Как вы можете видеть, у меня есть индикатор выполнения Bootstrap, который я показываю на ajaxstart(), а на странице, которую я вызываю, изменяю это значение строки выполнения после загрузки каждого элемента.

Это хорошо работает в Firefox, и я вижу индикатор выполнения, ожидая загрузки страницы, но он не работает в Chrome или IE.

Есть ли лучший способ сделать это? Правильно ли я делаю это или есть другой способ сделать это?

Например, получение $.ajax размера страницы в kb и обновление панели выполнения "на лету" при получении данных?

Я пытаюсь создать что-то похожее на страницу загрузки при загрузке Gmail.

4b9b3361

Ответ 1

Позвольте мне отсылать вас к этой странице, он описывает, как вы можете добавить слушателя progress event к объекту xhr (который работает только в эти браузеры, в старых браузерах вы просто полагаетесь на ту же базу, которую используете в настоящее время) в jquery.

Для справки я скопировал соответствующий код ниже (вас скорее всего интересует часть "Download progress" ):

$.ajax({
  xhr: function()
  {
    var xhr = new window.XMLHttpRequest();
    //Upload progress
    xhr.upload.addEventListener("progress", function(evt){
      if (evt.lengthComputable) {
        var percentComplete = evt.loaded / evt.total;
        //Do something with upload progress
        console.log(percentComplete);
      }
    }, false);
    //Download progress
    xhr.addEventListener("progress", function(evt){
      if (evt.lengthComputable) {
        var percentComplete = evt.loaded / evt.total;
        //Do something with download progress
        console.log(percentComplete);
      }
    }, false);
    return xhr;
  },
  type: 'POST',
  url: "/",
  data: {},
  success: function(data){
    //Do something success-ish
  }
});

Позвольте мне сказать, что это много переполнения для одного веб-сайта страницы и только действительно становится полезным для больших файлов. Кроме того, изображения и подобные носители не обрабатываются таким образом, и вам нужно будет контролировать загрузку изображений (или сделать это самостоятельно через ajax), чтобы сделать такую ​​систему идеальной.

Вот пример JSFiddle, показывающий это в действии: http://jsfiddle.net/vg389mnv/1/

Ответ 2

Вышеуказанный ответ правильный (рекомендуется). Пользовательский запрос xhr работает хорошо, я проверил его с вашим кодом (и большим файлом, чтобы увидеть фактический прогресс), может также скопировать его здесь:

$('.ajaxspl').on('click',function(e){
    e.preventDefault();

    var url=$(this).data('url'), wrap=$('body #wrap');

    //clean the wrapper
    wrap.slideUp().html('');

    //load page into wrapper
    console.log('starting ajax request');
    $.ajax({
        xhr: function() {
            var xhr = new window.XMLHttpRequest();
            xhr.addEventListener('progress', function(e) {
                if (e.lengthComputable) {
                    $('.progressbar .bar').css('width', '' + (100 * e.loaded / e.total) + '%');
                }
            });
            return xhr;
        }, 
        type: 'POST', 
        url: url, 
        data: {}, 
        complete: function(response, status, xhr) {
            console.log(response)
            wrap.html(response.responseText);
            wrap.slideDown();
        }
    });

});