LoginSignup
31
26

More than 5 years have passed since last update.

ajaxのダウンロードでプログレスバー

Last updated at Posted at 2015-09-13

コピペで済むかと思いきや、ajaxのダウンロードにプログレスバーを付けるソースが意外と転がってなかったのでメモとして。
jQueryとjQueryUIを使っています。

毎回表示されると邪魔

小さいデータをダウンロードする度に毎回一瞬プログレスバーが表示されるのも邪魔だったので、初回プログレスイベント時のダウンロード率でプログレスバーを表示するかどうか判断を入れる形にしました。

そもそも待ち時間をユーザに知らせる事がプログレスバーを付ける目的なので、一瞬プログレスバーが見えてもしょうがないなーという事です。

speedThreshold にプログレスバー有無の判断に使う初回ダウンロード率の閾値を設定しています。プログレスイベントが走るタイミングがブラウザや環境によって違いそうなので大まかにですが。
これも目的を考えると厳密さを求められる物じゃないという事で適当な実装を許してください。

デフォルトだと0.1になっていますがもっと大きい方がいいと思います。
これだと余程小さいファイル以外はプログレスバーが出てしまいますね。

ソースはこんな感じ

FileDownLoadProgress.js
var FileDownLoadProgress = {
  viewFlug:"firstTime",
  defaults:{
    url:"",
    type:"GET",
    dataType:"",
    success:function(){},
    error:function(){},
    speedThreshold:0.1
  },
  settings:{},
  loadFile:function(options){
    this.settings = $.extend({}, this.defaults, options);
    this.addProgressBar();
    $.ajax({
      url:this.settings.url,
      type:this.settings.type,
      context:this,
      success:function(data){
        this.settings.success();
        this.removeProgressBar();
      },
      error:function(data){
        this.settings.error();
        this.removeProgressBar();
      },
      xhr:function(){
        //passing ParentClass
        parentClass = this.context;
        //add event the Progress for XHR
        var xhr = $.ajaxSettings.xhr();
        xhr.addEventListener("progress",this.progress);
        return xhr;
      },
      progress:function(ev){
        //check speed at the first event
        if(parentClass.viewFlug == "firstTime"){
          parentClass.viewFlug = parentClass.checkProgressBarNecessity(ev);
        }
        if(parentClass.viewFlug){
          //change for value in progress
          $('#progress').progressbar('value',(ev.loaded / ev.total) * 100);
        }
      }
    });
  },
  addProgressBar:function(){
    $('body').append('<div id="progress">');
    $('#progress').progressbar({value:0,max:100});
  },
  removeProgressBar:function(){
    $('#progress').animate({opacity:0},500,function(){
      $(this).remove();
    });
    this.viewFlug = "firstTime";
  },
  checkProgressBarNecessity:function(ev){
    return ev.loaded / ev.total < this.settings.speedThreshold;
  }
}
index.html
$(function(){
  FileDownLoadProgress.loadFile({
    url:"data/1m",
    dataType:"json",
    success:function() {
      console.log("success");
    },
    error:function() {
      console.log("error");
    }
  });
});

jqueryのajax()にprogressイベントを書き足しているだけです。
追加したprogressイベントの中で自身のクラスを呼ぶ為に
context:thisparentClass = this.contextparentClass
という経路で渡しています。

ソースはgithubにも置いてあります。
https://github.com/pppp606/file_downLoad_progress


蛇足ですが余りにも英語力が無いので少し英語の勉強でもするかと適当な英語でコメントを書いてみる事にしました。割と酷い!

31
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
31
26