HTML5のprogress要素とjQueryでファイル読み込みのプログレスバーを表示する

HTML5のprogress要素とjQueryでファイル読み込みのプログレスバーを表示する

Posted at December 19,2012 1:55 AM
Tag:[HTML5, JavaScript, jQuery, progress]

HTML5のprogress要素とjQueryを組み合わせて、ファイルの読み込みのプログレスバーで表示するサンプルを紹介します。

1.progress要素とは

HTML5のprogress要素を使えば、進捗状況を示すプログレスバーを表示することができます。

progress要素は次のように記述します。value属性に作業の進捗度、max属性に作業の全体量を設定します。progress要素の内容にはフォールバックコンテンツを設定できます。

<progress max="100" value="50">50/100</progress>

progress要素をサポートしていれば下にプログレスバーが表示されます。サポートしていないブラウザであれば、フォールバックコンテンツである「50/100」が表示されます。

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:中断時のイベント
関連記事
zenback
人気エントリー
トラックバックURL


コメントする
greeting

*必須

*必須(非表示)


ご質問のコメントの回答については、内容あるいは多忙の場合、1週間以上かかる場合があります。また、すべてのご質問にはお答えできない可能性があります。予めご了承ください。

太字イタリックアンダーラインハイパーリンク引用
[サインインしない場合はここにCAPTCHAを表示します]

コメント投稿後にScript Errorや500エラーが表示された場合は、すぐに再送信せず、ブラウザの「戻る」ボタンで一旦エントリーのページに戻り(プレビュー画面で投稿した場合は、投稿内容をマウスコピーしてからエントリーのページに戻り)、ブラウザをリロードして投稿コメントが反映されていることを確認してください。

コメント欄に(X)HTMLタグやMTタグを記述される場合、「<」は「&lt;」、「>」は「&gt;」と入力してください。例えば「<$MTBlogURL$>」は「&lt;$MTBlogURL$&gt;」となります(全て半角文字)