新卒ノンプログラマーがプレビュー機能を作った。

<h2>はじめに</h2>
JSの練習がしたくて会社の同期に相談したところ、
「プレビュー機能を実装してみ」と宿題をもらいました。

せっかく作ったので、その過程をメモ書きとして残したいと思います。

＊ちなみに、僕は文系大学卒業のプログラミング初心者です。
<h3>参考にしたサイト</h3>
[File API入門：CodeGrid](https://app.codegrid.net/entry/file-api-filereader-api)
[JavaScript で File API を使用してファイルを読み取る](https://www.html5rocks.com/ja/tutorials/file/dndfiles/#toc-reading-files)

<h3>内容</h3>
今回の構成は大きく2つです。
<ul>
<li>プレビュー機能の確認</li>
<li>備忘録</li>
</ul>
簡単ですね。
文系の僕が勉強したことを残すだけなので、アドバイスとかあれば教えて下さい。
<h2>プレビュー機能の確認</h2>
以下が、出来上がったプレビュー機能です。
JavaScriptを使用してローカルからファイルを読み込み、ブラウザ上で表示します。

![preview.gif](https://qiita-image-store.s3.amazonaws.com/0/181563/43040436-ff4a-59e6-e27e-358627108856.gif)
<h2>メモ</h2>
今回メモしておくのは、以下の2つです。
<ul>
<li>画像の読み込み</li>
<li>表示</li>
</ul>
一つずつ見ていきましょう。
<h3>覚えたことその①「画像の読み込み」</h3>
まず、ローカルファイルを読み込むところまでです。

``` JS:preview.js
//1.ノード選択とFileReaderインスタンスの作成。
var inputFile = document.getElementById('file');
var reader = new FileReader();

//2.ファイルの取得
function fileChange(ev) {
  var target = ev.target;
  var file = target.files[0];
  var type = file.type;
  var size = file.size;
//3.ファイルの限定
  if ( type !== 'image/jpeg' ) {
    alert('選択できるファイルはJPEG画像だけです。');
    inputFile.value = '';
    return;
  }
reader.readAsDataURL(file);
}
inputFile.addEventListener('change', fileChange, false);
```

<!--FileAPIの活躍 -->
今回活躍したのは「FileAPI」です。
HTML5ではこのFileAPIを使用することで、ローカルファイルのデータをJSでやり取りできます。
気になる方は[「こちら（全部英語…）」](https://www.w3.org/TR/file-upload/)を参照してください。


ここで選択されたファイルは、fileオブジェクトの配列になるみたいですね。
ようはファイルをぶちこんで、読み込んだものが何かを判別するとこまでです。

<h3>覚えたことその②「表示」</h3>

``` JS:preview.js
function fileChange(ev) {
  var target = ev.target;
  var file = target.files[0];
  var type = file.type;
  var size = file.size;

  if ( type !== 'image/jpeg' ) {
    alert('選択できるファイルはJPEG画像だけです。');
    inputFile.value = '';
    return;
  }

  reader.onload = (function(theFile) {
    return function(e) {
      // Render thumbnail.
      var span = document.getElementById('list');
      span.innerHTML = ['<img class="thumb"  src="', e.target.result,
                        '" title="', escape(theFile.name), '" style="width:auto;height:400px;"/>'].join('');
    };
  })(file);

  reader.readAsDataURL(file);
}
```
次は読み込んだファイルをなんとかして表示します。
ここで、重要になるのがFileReaderの読み込みメソッドです。
以下の3つのメソッドを参考にして下さい。

| メソッド       |    引数  |    解説    |
|:-----------------:|:------------------:|:------------------:|
| readAsArrayBuff  |   Blob or File　  | ファイルをArrayBufferとして読み込む  　|
| readAsText       |    Blob or File 　|   ファイルをテキストとして読み    　　 |
| readAsURL        |    Blob or File 　|     ファイルをDataURLとして読み込む　|

読み込みが終了するとonroadイベントを発行するので、それを受けてHTML画像挿入する関数を作成します。
ここでは、ノード選択を行い、innerHTMLで読み込んだファイルとともに置き換えます。

これで、繰り返し画像選択を行ってもその度に画像を更新するようになりましたね。

あと、画像サイズによって表示が変わるのも気になったので、HTML上で直接Styleをあてて高さのみを固定しています。

<h2>まとめ</h2>
最終的にこんな感じになりました。
今回でファイルを読み込み、表示する場所を作成し表示するとこまでを実行しました。
なんかJSを書く上で大字になる「DOM」や「イベントハンドラ」といったものがよくわからない用語として出現したので、次はこいつを勉強してかるくまとめたいと思います。

``` html:index.html
<!DOCTYPE html>

<html lang="ja">
<head>
  <meta charset="utf-8">
  <title>Preview</title>
</head>
<body>
  <h3>jpegのみ選択可能です。</h3>
  <input type="file" id="file">
  <!-- <output id="list"></output> -->
  <div id="list"></div>

<script>

var inputFile = document.getElementById('file');
var reader = new FileReader();

function fileChange(ev) {
  var target = ev.target;
  var file = target.files[0];
  var type = file.type;
  var size = file.size;

  if ( type !== 'image/jpeg' ) {
    alert('選択できるファイルはJPEG画像だけです。');
    inputFile.value = '';
    return;
  }

  reader.onload = (function(theFile) {
    return function(e) {
      // Render thumbnail.
      var span = document.getElementById('list');
      span.innerHTML = ['<img class="thumb"  src="', e.target.result,
                        '" title="', escape(theFile.name), '" style="width:auto;height:400px;"/>'].join('');
    };
  })(file);

  reader.readAsDataURL(file);
}

function fileLoad() {
  console.log(reader.result);
}

inputFile.addEventListener('change', fileChange, false);
reader.addEventListener('load', fileLoad, false);

</script>
</body>
</html>
```