HTML5のprogress要素とjQueryでファイル読み込みのプログレスバーを表示する
HTML5のprogress要素とjQueryを組み合わせて、ファイルの読み込みのプログレスバーで表示するサンプルを紹介します。
1.progress要素とは
HTML5のprogress要素を使えば、進捗状況を示すプログレスバーを表示することができます。
progress要素は次のように記述します。value属性に作業の進捗度、max属性に作業の全体量を設定します。progress要素の内容にはフォールバックコンテンツを設定できます。
<progress max="100" value="50">50/100</progress>
progress要素をサポートしていれば下にプログレスバーが表示されます。サポートしていないブラウザであれば、フォールバックコンテンツである「50/100」が表示されます。
2.サンプル
progress要素とJavaScriptのFileReaderオブジェクトを組み合わせた簡単なサンプルを作ってみました。
このサンプルはファイルを選択した直後に、ファイルの読み込み状況をプログレスバーで表示します。ファイルサイズが小さすぎるとプログレスバーはすぐに終わってしまうので予めご了承ください。
ネットでいろいろ調べてみたのですが、setIntervalで単純に値を増加させるものや、古い情報でprogress要素を使っていないものなど、progress要素を使った実用的なサンプルはほとんど出回っていないようです(このエントリーのサンプルが実用的かどうかは分かりませんが)。
Google Chromeでは正常に動作しましたが、Firefoxでは途中で停止する場合があります。
サンプルコードは次のとおりです(必要最低限部分のみ抜粋)。
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8/jquery.min.js"></script>
<script>
jQuery(function(){
jQuery('#entry-file').change(function(e) {
var file = e.target.files || e.dataTransfer.files;
readFile(file[0]);
});
});
var readFile = function(file){
var status = jQuery("#status");
var fallback = jQuery("#fallback");
var info = jQuery("#info");
var reader = new FileReader();
reader.onprogress = function(e){
var loaded = e.loaded;
var total = e.total;
var per = (loaded/total) * 100;
per = per.toFixed(0);
status.val(per);
info.text(per + "% (" + loaded + "/" + total + "byte)");
fallback.text(info.text());
}
reader.onerror = function(e){
var error_number = e.target.error.code;
info.innerHTML += "error:" + error_number;
}
reader.readAsDataURL(file);
};
</script>
<input type="file" name="file_customfield_cfimage" id="entry-file" class="fi" />
<div id="progressbar">
<progress id="status" max="100" value="0"><span id="fallback"></span></progress>
<div id="info"></div>
</div>
以下、サンプルコードの説明です。
ファイルが選択されたときにchangeイベントを使ってreadFile()を起動します。
jQuery(function(){
jQuery('#entry-file').change(function(e) {
var file = e.target.files || e.dataTransfer.files;
readFile(file[0]);
});
});
readFile()ではreadAsDataURL()を使ってデータを読み込みます。readAsDataURL()はURLスキームのデータとして、バイナリファイルの中身を読み込むためのメソッドです。
var readFile = function(file){
…中略…
reader.readAsDataURL(file);
};
FileReaderのイベント属性onprogressを実装して、読み込み作業中のイベントをハンドリングします。この中でe.loadedでローディング中のサイズ、e.totalで全体サイズが取得できるので、これらから進捗状況を計算してprogress要素のvalue属性に設定しています。あわせてフォールバックコンテンツも生成しています。
var readFile = function(file){
…中略…
reader.onprogress = function(e){
var loaded = e.loaded;
var total = e.total;
var per = (loaded/total) * 100;
per = per.toFixed(0);
status.val(per);
info.text(per + "% (" + loaded + "/" + total + "byte)");
fallback.text(info.text());
}
…中略…
};
3.FileReaderのイベント属性
話がややそれますが、FileReaderのイベント属性には以下のものが用意されているので、必要に応じて実装するとよいでしょう。
- onloadstart:読み込み開始時のイベント
- onprogress:読み込み作業中のイベント
- onload:正常に読み込んだときのイベント
- onloadend:読み込み処理完了時のイベント
- onerror:読み込みエラー時のイベント
- onabort:中断時のイベント