コピペで済むかと思いきや、ajaxのダウンロードにプログレスバーを付けるソースが意外と転がってなかったのでメモとして。
jQueryとjQueryUIを使っています。
毎回表示されると邪魔
小さいデータをダウンロードする度に毎回一瞬プログレスバーが表示されるのも邪魔だったので、初回プログレスイベント時のダウンロード率でプログレスバーを表示するかどうか判断を入れる形にしました。
そもそも待ち時間をユーザに知らせる事がプログレスバーを付ける目的なので、一瞬プログレスバーが見えてもしょうがないなーという事です。
speedThreshold
にプログレスバー有無の判断に使う初回ダウンロード率の閾値を設定しています。プログレスイベントが走るタイミングがブラウザや環境によって違いそうなので大まかにですが。
これも目的を考えると厳密さを求められる物じゃないという事で適当な実装を許してください。
デフォルトだと0.1
になっていますがもっと大きい方がいいと思います。
これだと余程小さいファイル以外はプログレスバーが出てしまいますね。
ソースはこんな感じ
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;
}
}
$(function(){
FileDownLoadProgress.loadFile({
url:"data/1m",
dataType:"json",
success:function() {
console.log("success");
},
error:function() {
console.log("error");
}
});
});
jqueryのajax()
にprogressイベントを書き足しているだけです。
追加したprogressイベントの中で自身のクラスを呼ぶ為に
context:this
→ parentClass = this.context
→ parentClass
という経路で渡しています。
ソースはgithubにも置いてあります。
https://github.com/pppp606/file_downLoad_progress
蛇足ですが余りにも英語力が無いので少し英語の勉強でもするかと適当な英語でコメントを書いてみる事にしました。割と酷い!