web-dev-qa-db-ja.com

単一ページのWebサイトで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では動作しません。

これを行うためのより良い方法はありますか?私はこれを正しくやっていますか、これを行う別の方法がありますか?

たとえば、KB単位で_$.ajax_ページサイズを取得し、データの受信時に進行状況バーを即座に更新しますか?

Gmailの読み込み中に、読み込みページに似たものを作成しようとしています。

33
Zalaboza

このページ を参照することを許可します。progress event jhrのxhrオブジェクトのリスナー( これらのブラウザー でのみ動作し、古いブラウザーでは、現在使用している同じベースに依存しているだけです)。

参考のために、以下の関連コードをコピーしました(おそらく、「ダウンロードの進行状況」の部分にのみ興味があるでしょう)

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

ただし、これは1ページのWebサイトでは非常にやり過ぎであり、大きなファイルに対してのみ有効になります。さらに、画像や類似のメディアはこの方法で処理されないため、このようなシステムを完璧にするには、画像の読み込みを監視する(またはajaxを使用して自分で行う)必要があります。

これが動作していることを示すJSFiddleです: http://jsfiddle.net/vg389mnv/1/

74
David Mulder

上記の答えは正しいです(支持されています)。カスタム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();
        }
    });

});
11
Laszlo R.