Javascriptで簡単な画像プレビュー機能を作成してみる

プロフィール画像をアップロードした時などプレビューできるできると便利ですよね? 今日は簡易的なものですが、作っていきます。

こちらアップロードした後の画面です。

f:id:top_men:20181010193215p:plain

準備

必要なものはブラウザとエディタです。それだけ。

見た目を整える

まずは、簡単な見た目の部分から作ります。

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=1, initial-scale=1.0'>
  <meta http-equiv='X-UA-Compatible' content='ie=edge'>
  <title>ファイルプレビュー機能について</title>
  <link href="https://use.fontawesome.com/releases/v5.0.6/css/all.css" rel="stylesheet">
  <link rel='stylesheet' href='style.css'>
</head>
<body>
  <div class='wrap'>
    <div>
      <label class="file_photo_wrap" for="file_photo">
        <i class="fas fa-camera fa-4x"></i>
        <input type='file' id="file_photo">
      </label>
      <div class="preview_img" id="preview">
        <img src='' class="preview_img_content" id="preview_img_data" alt=''>
        <span class="updated_text">アップロード済み</span>
      </div>
    </div>
  <script src="main.js"></script>
</body>
</html>

アイコンを使いたかったのでFontawesomeを読み込んでいます。

.wrap {
  justify-content: center;
  display: flex;
}

.file_photo_wrap {
  display: block;
  width: 90px;
  height: 90px;
  padding: 50px;
  margin: 100px auto 0 auto;
  border-radius: 50%;
  background: #4f4fe9;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 1;
  transition: opacity .5s;
}

.file_photo_wrap:hover {
  opacity: .6;
}

input[type="file"] {
  display: none;
}

.fa-camera {
  color: #fff;
  cursor: pointer;
}
.preview_img {
  display: none;
  border: 1px solid #ccc;
  width: 160px;
  height: 100px;
  padding: 10px;
  margin-top: 20px;
}

.preview_img.is-active {
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
}

.preview_img_content {
  height: 100%;
}

.updated_text {
  position: absolute;
  bottom: -30px;
}

プレビュー機能を作成

const target_el = document.getElementById("file_photo");
target_el.addEventListener("change", (e) => {
  const files = target_el.files;
  if (e.target.files.length) {
    const reader = new FileReader();
    reader.readAsDataURL(files[0]);
    reader.onload = () => {
      document.getElementById("preview").classList.add("is-active");
      document.getElementById("preview_img_data").setAttribute("src", reader.result);
    }
  }
})

このコードではまず2行目でinputタグのchangeイベントを取得します。

target_el.addEventListener("change", (e) => {}

その後3行目のfilesでファイル情報を取得しています。

 const files = target_el.files;

ファイルの数が1つでもあればif文の中を通ります。 5行目のFileReader オブジェクトを使用するとユーザのコンピュータ内にあるファイルを非同期的に読み込むことが出来ます。

以下参考にしてみてください。

developer.mozilla.org

FileReader.readAsDataURL()は 指定されたBlobオブジェクトを読み込みます。 BlobはBinary Large Object の略になります。Blob は文字列や巨大な画像、音声ファイル、動画ファイルなどを扱うことができます。

FileReader.onloadファイルの読み込みが成功した時に呼ばれるイベントです。

プレビュー画像のimgタグのsrc属性にreader.resultという値が入ります。 このresultというプロパティには、ファイルのデータを示すデータURLが入ります。

とても簡単なものではありますが、これで完成です。

プレビュー機能があるだけでUXの向上に繋がると思います。