はじめに
JavaScriptとFile APIを使い、ユーザーがローカルの画像ファイルを選択し、
選択された画像のプレビューを以下のようにブラウザに表示させる方法をまとめました。
ソースコード
▼HTML
<input type="file" id="input">
<div id="preview"></div>
▼JavaScript
document.addEventListener('DOMContentLoaded', () => { // ①
const input = document.getElementById('input'); // ②
const preview = document.getElementById('preview'); // ③
input.addEventListener('change', event => { // ④
const file = event.target.files[0]; // ⑤
if (file.type.match(/image\/*/)) { // ⑥
const reader = new FileReader(); // ⑦
reader.addEventListener('load', event => { // ⑧
preview.innerHTML = '<img src="' + event.target.result + '">'; // ⑨
});
reader.readAsDataURL(file); // ⑩
}
else {
alert("画像ファイルを指定してください。");
input.value = ''; // ⑪
return false; // ⑫
}
});
});
解説
以下、JavaScriptの解説をしていきます。
▼①について
document.addEventListener('DOMContentLoaded', () => {
ここでは、HTMLの読み込みが終わった後に関数が実行されるようにアロー関数を用いて記述しています。
▼②、③について
const input = document.getElementById('input'); // ②
const preview = document.getElementById('preview'); // ③
②ではHTML内のidがinput
の要素を定数input
に代入し、
③ではidがpreview
の要素を定数preview
に代入しています。
▼④について
input.addEventListener("change", event => {
ここでは、②で定義したinput
でchange
イベントが発生した際に、
event
の中の関数を実行するように記述しています。
change
イベントとは、<input>
要素などにおいて、
ユーザーにより要素の値が変更されたときに発生するイベントです。
つまり、上記のように記述することで、
ユーザーが画像を選択したときにイベントが実行されるようにしています。
さらに、ここではevent
をアロー関数の引数として渡すことで、
{}
内でイベント発生時の情報を利用できるようにしています。
アロー関数は引数が0か2つ以上の場合は括弧()
が必要になりますが、
引数が1つの場合は括弧を省略することができます。
▼⑤について
const file = event.target.files[0];
選択されたファイルをfile
に代入しています。
event.target
と記述することで、イベントの発生源であるオブジェクトを取得することができます。
イベントで取得した要素の値を使いたいときは、このようにtarget
属性を指定します。
今回のようにHTMLでinput
要素のタイプをfile
と指定している場合は、
FileList
というオブジェクトの中に選択されたファイルが格納され、
event.target.files
とすることでそのオブジェクトを取得できます。
また、FileList
は配列となっているため、1枚取得する場合は[0]
を加えます。
console.log(event);
などと記述することで、event
の中身の構造が理解しやすくなると思います。
以下、event.target.files
の中身です。
▼⑥について
if (file.type.match(/image\/*/)) {
ここでは、選択されたファイルの形式が画像である場合のことをif文で記述しています。
file.type
と書くことで、ファイルの形式を取得できます。
⑤の解説で載せたevent.target.files
の中身の画像を見ると、
ファイルのオブジェクトの中にtype: "image/jpeg"
と書かれているのがわかりますね。
match(/image\/*/)
では、file.type
で取得した値の文字列が
"image/○○"となっているかを正規表現で確認しています。
▼⑦について
const reader = new FileReader();
FileReader
というファイルを読み込むオブジェクトを新しく作成し、定数reader
に代入しています。
▼⑧〜⑩について
reader.addEventListener('load', event => { // ⑧
preview.innerHTML = '<img src="' + event.target.result + '">'; // ⑨
});
reader.readAsDataURL(file); // ⑩
⑧では、ファイルの読み込みが完了した時に発生するイベントを定義しています。
一旦⑨を飛ばして⑩の解説をすると、⑩ではファイルを読み込んでいます。
readAsDataURL
は、ファイルを読み込み、データをbase64という形式のURLに変換するメソッドです。
ここでは⑤で定義したfile
を読み込み、変換しています。
このメソッドではファイルの読み込みが終わると、result
属性に変換済みのURLを格納します。
また、⑩でファイルの読み込みが終わるとreader
のload
イベントが発生し、
⑧と⑨で定義した関数が呼ばれます。
⑨では、③で定義したpreview
の要素の中身に選択した画像を挿入しています。
右辺でimg
要素のsrc
属性に、⑩で変換されたデータのURLを入れています。
▼⑪、⑫について
else {
alert("画像ファイルを指定してください。");
input.value = ''; // ⑪
return false; // ⑫
}
ここでは、ユーザーが選択したファイルが画像ではなかった場合の処理を記述しています。
⑪では、②で定義したinput
要素の値を空にしています。
また、⑫で画像以外が選択された場合は処理が止まるように記述しています。
参考にしたサイト・動画
Web アプリケーションからのファイルの使用
FileAPIのreadAsDataURLメソッドでローカルの画像ファイルをブラウザに表示させる
画像をアップロード&プレビューしよう【わかりすぎて怖いJavaScript入門】