HTML5 の FileAPI を用いたファイル選択の改善手法
こんにちは、本間です。
HTML5 から登場した FileAPI を用いると、JavaScript でユーザーの選択したファイル情報を取得することができるようになります。これにより、今までは ファイル選択のフォームで送信 というだけの HTML フォームだったのが、ファイル選択(複数化)したらファイル名やファイルチェックをその時点でしたり、ドラッグ&ドラッグでファイルを引っ張ってくる などといったよりユーザーに優しいファイル操作を実現できるようになります。
今回はファイル選択フォームとドラッグ&ドロップフォームの2つを簡単にご紹介します。
ファイル選択
今までのよくある input type="file"
です。
<input type="file" id="upload-file" accept="audio/*">
accept 属性を入れると、ファイル選択時に指定のファイルタイプだけしか選択できないようになります。また、以下のように JavaScript を記述すると、ファイル選択した直後のイベントを取得できます。選択した時点でファイルの検証(ファイルサイズやファイルタイプのなど)をするには以下のような形になります。
$("#upload-file").on("change", function(e) {
var tmpfile = e.target.files[0];
console.log(tmpfile);
if (validateFile(tmpfile)) {
console.log("検証成功")
} else {
$('#upload-file').val(""); //remove the file
}
});
ドラッグ & ドロップ選択
最近のWebサービスならほぼ間違いなくあるドラッグ & ドロップによるファイル選択。これも HTML5 による恩恵です。
<div id="drop-zone"><span class="here">ここにファイルをドラッグ</span></div>
CSS を調整し、 #drop-zone
をドロップしやすい程の領域を作っておきます。
$("#drop-zone").on("drop",function(e){
e.preventDefault();
$(this).removeClass("dragover");
console.log(e.originalEvent.dataTransfer.files);
var tmpfile = e.originalEvent.dataTransfer.files[0];
if (validateFile(tmpfile)) {
console.log("検証成功")
$("#drop-zone .here").text(file.name + " (" + file.type + ")");
}
});
$("#drop-zone").on("dragover",function(e){
e.preventDefault();
$(this).addClass("dragover");
});
$("#drop-zone").on("dragleave",function(e){
e.preventDefault();
$(this).removeClass("dragover");
});
非常にシンプルです。ドラッグで対象領域に持って行く後、 dragover イベントが発生します。この時にcss でドラッグできる所に来たよ、とユーザーに知らせることができます。
共通点
ファイル選択からでもドラッグ&ドロップからでも、どちらもファイルオブジェクトをJavaScript で持つことになります。
これをそのまま Form のデータとしてで送信することもできますし、データは Base64エンコードされているため、画像(img)や音楽(audio)タグのsrcに埋め込むことでプレビューのような形でそのまま最適な形で表示することもできます。
終わりに
今まではドラッグ&ドロップでファイルアップロードできるのはすごい!という風潮でしたが、これからはもはやドラッグ&ドロップがなくてはならないという標準的な機能として普及していくことでしょう。
その時に備えて、早めにファイル選択フォームだけでなく、ドラッグ&ドロップでのファイル選択もできるようなWebアプリケーションに更新することが求められています。