こんにちは、橋本です。
今回は小ネタを1つ紹介したいと思います。 画像投稿フォームを作る際に、投稿された画像を即時表示したいなんてことありませんか? そんなときに便利なのが、HTML5で追加されたFile API。
File APIを使えば、投稿された画像(正確には、選択されたローカルファイル)の情報を取得することができます。
では、画像投稿機能のサンプルを元に、File APIの使い方を見て行きましょう。
File API自体はjQueryと何の関係もありませんが、いろいろと面倒なので今回もjQueryを使っています。
サンプル
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
<title>サンプル</title>
</head>
<body>
<input class="fileInput" type="file" /><br>
<a href="https://www.asial.co.jp &mode=1" class="popupimg"><img src="https://www.asial.co.jp"></a>
<script>
$('.fileInput').change(function(){
// 1. 選択されたファイルがない場合は何もせずにreturn
if (!this.files.length) {
return;
}
var file = this.files[0], // 2. files配列にファイルが入っています
$_img = $(this).siblings('img'), // 3. jQueryのsiblingsメソッドで兄弟のimgを取得
fileReader = new FileReader(); // 4. ファイルを読み込むFileReaderオブジェクト
// 5. 読み込みが完了した際のイベントハンドラ。imgのsrcにデータをセット
fileReader.onload = function(event) {
// 読み込んだデータをimgに設定
$_img.attr('src', event.target.result);
};
// 6. 画像読み込み
fileReader.readAsDataURL(file);
});
</script>
</body>
</html>
サンプルのコメントに番号をふっておいたので、番号に沿って説明していきたいと思います。
まず1ですが、ファイルの情報は、input要素のfiles配列にFileオブジェクトとして格納されています。
ですので、input要素のfiles配列のlengthでファイルの選択の有無を確認し、選択されていない場合には処理を終えるよう設定しています。
2は上記で説明したとおり、files配列にファイルが格納されていますので、そこから0番目の要素としてファイルを取得しています。
3は取得したファイルのデータを設定するimgタグを予め変数に格納しています。jQueryオブジェクトだということを明示するために、"$_"プレフィクスをつけています。
4はファイルを読み込むためのFileReaderオブジェクトをインスタンス化し、変数に入れています。これが今回のキモです。
FileReaderオブジェクトはファイルを読み込むためのオブジェクトです。
各種メソッドにFileオブジェクトを渡すことで、非同期でデータの読み込みを行います。
以下の4つのメソッドがあるのですが、よく使うのは最初の2つです。画像に関しては最初の1つでいいと思います。
readAsDataURL(file); // Data URLスキームの形式で読み出す
readAsText(file, encoding); // テキストとして読み出す。エンコーディングを指定可。
readAsBinaryString(file); // バイナリデータとして読みだす。
readAsArrayBuffer(file); // ArrayBufferを返す。詳細不明
5はFileReaderオブジェクトのonloadイベントのイベントハンドラを設定しています。
上記でちょっと触れたんですが、FileReaderオブジェクトのファイルの読み出しは非同期となりますので、イベントハンドラを設定する必要があります。
6でデータの読み込みを開始しています。今回は取得したデータをそのままimgタグのsrcにつっこむので、readAsDataURLメソッドを使用しています。
どうでしょう。非常に簡単ですね。
このサンプルをちょこっといじることで、選択されたファイルをajaxを使って即時サーバに送って保存するといったことも可能になります。
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
<title>サンプル</title>
</head>
<body>
<input class="fileInput" type="file" /><br>
<a href="https://www.asial.co.jp &mode=1" class="popupimg"><img src="https://www.asial.co.jp"></a>
<script>
$('.fileInput').change(function(){
// 1. 選択されたファイルがない場合は何もせずにreturn
if (!this.files.length) {
return;
}
var file = this.files[0], // 2. files配列にファイルが入っています
$_img = $(this).siblings('img'), // 3. jQueryのsiblingsメソッドで兄弟のimgを取得
fileReader = new FileReader(); // 4. ファイルを読み込むFileReaderオブジェクト
// 5. 読み込みが完了した際のイベントハンドラ。サーバにデータを送信
fileReader.onload = function(event) {
$.ajax({
type: 'POST',
url: 'http://fairuwookurusa-ba.com',
data: {file: event.target.result},
success: function(){
$_img.attr('src', event.target.result);
},
error: function(a, b, c){
alert('ファイルのアップロードに失敗しました');
console.log(a, b, c);
}
});
};
// 6. 画像読み込み
fileReader.readAsDataURL(file);
});
</script>
</body>
</html>
またまた簡単ですね。サーバに送る際には、readAsBinaryStringメソッドを使って、バイナリとして取得してもいいかもしれませんね。
以上、簡単な小ネタの紹介でした。