[Javascript] type=fileで画像を選択した際に、プレビュー表示をするサンプル

2017年3月21日

Javascript テクノロジー プログラミング

WEBページがインタラクティブ対応して当たり前のようになった機能が多いのですが、アップロードする画像を事前にプレビュー表示するなんて機能は、Web2.0やHTML5ともてはやされるようになってきてからのブラウザのFileAPI機能が発達したおかげでしょう。 そもそも、WEBサービスを作るときには、こうしたWebAPI機能を駆使して見栄えも操作性も直感的にする必要があります。 動画も、3Dも、スマホセンサーアクセスなども、HTMLから操作できるようになっているので、もはやスマホのネイティブアプリではなく、HTML5の方が開発工程などにおいてももてはやされているという噂もチラホラ聞くようになりました。 今回は、<input type="file"/>というファイルアップローダを作った時に、画像であれば、プレビューしてくれる機能がとても使う機会が多いので、備忘録として、サンプルを載せておきたいと思います。

各種ソースコード

<!DOCTYPE html> <html lang="js"> <head> <meta charset="utf-8"> <title>File Upload Sample</title> <link type="text/css" rel="stylesheet" src="common.css"> <script type="text/javascript" src="common.js"></script> </head> <body> <h1>File Uploader [Image]</h1> <div id="imgViewArea"></div> <div> <input type="file" name="file" id="file"> <button>Image Upload</button> </div> </body> </html> #imgViewArea{ width:128px; min-height:64px; border:1px solid black; margin:4px; padding:0; background-color:#CCC; font-size:0; } #imgViewArea img{ width:100%; height:auto; max-width:100%; max-height:100%; margin:0; padding:0; border:0; } ;(function(){ function $$(){ this.__construct(); }; $$.prototype.__construct = function(){ if(document.readyState === "complete"){ this.loaded(); } else{ window.addEventListener("load", this.loaded , false); } }; $$.prototype.loaded = function(){ var fileElm = document.getElementById("file"); if(fileElm===null){return} fileElm.onchange = $$.prototype.fileEvent; }; $$.prototype.fileEvent = function(event){ if(!event.target.files.length){return} var fileReader = new FileReader(); fileReader.onload = function(){console.log(this.result); var imgViewArea = document.getElementById("imgViewArea"); imgViewArea.innerHTML = ""; var img = document.createElement("img"); img.src = this.result; imgViewArea.appendChild(img); } fileReader.readAsDataURL(event.target.files[0]) ; }; new $$; })();

解説

htmlとcssの解説は省きます。 基本的にJS部分のみでいいと思いますんで。

JSの全体構成

少し拡大するプログラム構成を意識していますが、スニペットとして使いたい人は、 fileElm.onchange = $$.prototype.fileEvent; の部分は、type=fileのエレメントで、ファイルを選択した時に、onchangeイベントが発火するので、その関数をしていしています。 そして肝心なのが、$$.prototype.fileEvent関数という事。

multipleの場合の対応

type=fileでは複数ファイルの選択もできますが、今回はあえて行なっていません。 そして、エレメントの項目が消された時は処理を除外するため、下記1行を入れています。 if(!event.target.files.length){return}

FileAPIのセット

var fileReader = new FileReader(); fileReader.onload = function(){}; fileReader.readAsDataURL(event.target.files[0]) ; 上記が基本構成で、fileAPIのclassを定義したfileReaderが指定された画像がブラウザに読み込まれたタイミングを計るためにonloadイベントをセットしてます。 そしてその後にreadAsDataURLで指定された画像をセットしているという内容です。

onload内処理

今回は、画像を表示するエリアをdivで事前に用意して、その中を毎回一度空にしてから、imgエレメントを作成してappendChildしています。 var img = document.createElement("img"); img.src = this.result; ちなみに、見ればわかるのですが、画像の内部パスは「this.result」で取得できるので、まんまsrc属性にいれるだけでいいんですね。 今回はソースのみでサンプルページは容易していません。 何かのツールで使ったらまた掲載します。