JavaScriptとprogressタグによる進捗バーの表示
今までWebで表示するプログレスバー(進捗状況が表示される横棒)といえばDIVタグで描くもの、と思い込んでいたのですが、最近になってHTML5にはProgressタグなるものがあると知ったので早速使ってみることにしました。
Progressタグの表示例
サンプルコード
例1:<progress></progress><br>
例2:<progress min="0" max="100" value="50"></progress>
実行結果
例1:
例2:
解説
Progressタグをそのまま書いただけだと、左右に行ったり来たりする※バーが表示され、min/maxを指定した場合、valueの数値に合わせた長さにバーが伸びるようです。
例1の左右に行ったりきたりするバー、意外と使い勝手良さそうじゃないですかね。
マジメに作るなら、長い処理をしている最中は途中でプログレスバーを適切に伸ばしたほうが良いけど、せいぜい数秒しかかからないのがわかりきっている場合とか、砂時計のようなひとまず働いてますよアピールにちょうど良さそう。
画面遷移の前にいったん表示したり、FormタグでのPOST前に表示したり。
JavaScriptでProgressタグ操作してみる
サンプルコード
<progress id="p1" min="0" max="100" value="0"></progress>
<button onclick="proc1();">開始</button>
<script>
function proc1()
{
if (document.getElementById('p1').value < 100 ) {
document.getElementById('p1').value++;
setTimeout(proc1, 100);
}
}
</script>
実行結果
[開始]ボタンを押すと100ミリ秒(10分の1秒)に1%ずつ、計10秒かけてプログレスバーが右に伸びます。
解説
ボタン押されたらproc1関数が呼び出され、そこではプログレスバーのvalueを+1して、またsetTimeoutで自分自身を呼び出す、というシンプルな作りです。
Progressタグがなかった頃から比べるとだいぶシンプルな書き方が出来ますね。
JavaScriptとspan/divタグでプログレスバーを表現する
せっかくなので従来の(progressタグを使わない)やり方も紹介。
サンプルコード
<span style="display:inline-block;width:180px;border:1px solid #cccccc;">
<div id="p2" style="width:0px;background-color:green;height:16px;"></div>
</span>
<button onclick="proc2();">開始</button>
<script>
var p2_value = 0;
function proc2()
{
if (p2_value < 100 ) {
document.getElementById('p2').style.width = ++p2_value + '%';
setTimeout(proc2, 100);
}
}
</script>
実行結果
解説
spanタグで幅180px、高さ16pxのグレー色の枠を作り、その中にdivタグを入れ、JavaScriptでdivのwidthを0~100%まで幅を変えている感じです。
JavaSciprtでピクセルの計算をしている例も見かけますが、%表記にしておけばバーの長さを変えたくなったとしても外枠のspanタグだけ修正すれば良いので、このほうが簡単かな、と思います。
progressタグのほうが実装は簡単ですが、バーの中に文字を入れたりはできないっぽいので、細かくカスタマイズしたいときは従来のspanやdivタグを駆使するほうが良いかな?
このあたりは使い分けってことで。
まとめ
- HTML5ではProgressタグがあるため進捗バーの表示が簡単
- バーが左右に動くだけならJavaScriptすら不要
- バーを設定どおりに動かしたい場合はmin/maxで最小値/最大値を設定し、valueで現在値を設定する
- Progressの中(バーの中)には文字が書けないようなので、そういったカスタマイズをしたい場合は従来のspan/divタグを使う方法が良いかも
といったところでしょうか。
あと、progressタグに何も指定しなかったときの動作はChrome/IE/Edgeは「動作中」を表すような表現なのに対し、FireFoxは100%の表示になってしまうので、クロスブラウザ対応を考えている場合は少し工夫が必要そうですね。