0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

jQueryを使って選択した画像をプレビュー表示させる

Posted at

はじめに

画像投稿する際、投稿画像選択時に選択した画像(今回は1枚のみ)をプレビュー表示するまでを解説したいと思います。

完成イメージ

imageupload.gif

#環境
MacOS 10.15.7
ruby 2.6.5
Ruby on Rails 6.0.0

前提条件

jQueryの導入が完了済みであること。

作業していきましょう!

①画像投稿フォームを作成

はじめに、画像の投稿フォームを作成していきます。
▼フォームの完成イメージ
imageinput 1.png

html.erb

<div class='image'>
  <label class="labelName" for="imageSpace">Photo </label>
  <input  class='imageInput' placeholder='写真を選択してください' type='file'>
</div>
<div class="prevImageBox">
</div>
scss

.image {
  color: #ffffff;
  padding: 10px 16px 8px;
  margin-top: 8px;
  display: flex;
}

.imageInput {
  color: #000000;
  background-color: #fff;
  border-radius: 5px;
  border: 1px solid #ccc;
  margin-left: 10px;
}

上記の記述で出来上がりです。
(フォームの背景の設定については今回省略しております)

htmlの

<div class="prevImageBox">
</div>

の部分については、選択した画像をプレビュー表示させるための要素(箱)になります。

②jQueryで実装していく

まずはjsファイルを作成します。ファイル名はなんでも良いですが今回は「image.js」というファイルを作成して、jQueryの記述をしていきます。

image.js

$(function(){
  
  // <div class='image'>の直後の兄弟要素(今回の場合は<div class='prevImageBox'>がそれに該当)を取得。
  const prevImage = $('.image').next();

  // プレビュー表示部分のhtml
  function buildHTML(id,image) {
    let html = `<div class="prevImageBox">
                  <div class="upper-box">
                    <img src=${image} alt="preview">
                  </div>
                  <div class="lower-box">
                    <div class="delete-box">
                      <div class="delete-btn" data-delete-id= ${id}>削除</div>
                    </div>
                  </div>
                </div>`
    return html;
  }
  

  // ===========================================
  // imageInputの値が変更したとき(画像が選択された時)の処理
  // ===========================================
  $(document).on('change', '.imageInput', function() {
    //imageInputのidを取得
    let id = $(this).attr('id');
    //選択したfile(画像)のオブジェクトを取得
    let file = this.files[0];
    // PC内にあるファイルをアプリケーションに非同期で読み込む
    let reader = new FileReader();
    //readAsDataURLで指定したFileオブジェクトを読み込む
    reader.readAsDataURL(file);
    //読み込み時に発火するイベント
    reader.onload = function() {
      // 直前に実行されたイベント(imageファイルの読み込み)を変数imageに代入
      let image = this.result;
      //htmlを作成
      let html = buildHTML(id,image);
      //<div class='prevImageBox>にプレビュー画像を追加
      $(prevImage).append(html);
      //画像が選択された状態(プレビュー画像表示中)だと、画像選択フォームを隠す
      $('.imageInput').hide();
    }
  });


  // ==================================
  //   プレビュー画像を削除する場合の処理
  // ==================================
  $(document).on('click', '.delete-btn', function() {
    let id = $(this).attr('data-delete-id')
    //画像を消去
    $(this).parent().parent().parent().remove();
    //画像選択フォームの中身を空にする
    $('.imageInput').val("");
    //画像選択フォームを表示
    $('.imageInput').show();
  });
});

以上が、jQueryの記述となります。

プレビュー画像部分のCSSも載せておきます。

プレビュー画像部分のcss
.prevImageBox {
  display: block;
  width: 10vw;
  margin: 0 15px 10px 0;
  padding-left: 45px;
  .upper-box {
    height: 100%;
    width: 100%;
    img {
      width: 100%;
      height: 100%;
    }
  }
  .lower-box {
    display: flex;
    text-align: center;
    .delete-box {
      color: #00b0ff;
      width: 100%;
      height: 50px;
      line-height: 50px;
      border: 1px solid #eee;
      background: #f5f5f5;
      display: flex;
      justify-content: center;
      align-items: center;
      cursor: pointer;
      .delete-btn {
        background-color: #f5f5f5;
        line-height: 40px;
        width: 60px;
      }
    }
  }
}

プレビュー画像のサイズについては.prevImageBoxのwidthで調整してみてください。

簡単に解説

4行目で

const prevImage = $('.image').next();

として、「nextメソッド」を使って、imageクラスの兄弟要素にあたるprevImageBoxを取得して、それを変数prevImageに格納しています。

nextメソッドについては以下が参考になります。
http://js.studio-kingdom.com/jquery/traversing/next

6〜19行目の

function buildHTML(id,image) {
    let html = `<div class="prevImageBox">
                  <div class="upper-box">
                    <img src=${image} alt="preview">
                  </div>
                  <div class="lower-box">
                    <div class="delete-box">
                      <div class="delete-btn" data-delete-id= ${id}>削除</div>
                    </div>
                  </div>
                </div>`
    return html;
  }

に関しては、実際に表示させるプレビュー画像部分のhtmlとなります。
構造としては、PrevImageBoxという大枠の中に、upper-boxとlower-boxの2段に分けた構造になります。
upper-boxにはイメージ画像を導入し、lower-boxには画像削除用ボタンを搭載する形となっております。

あとは、
画像を選択する時の処理

// ===========================================
  // imageInputの値が変更したとき(画像が選択された時)の処理
  // ===========================================
  $(document).on('change', '.imageInput', function() {
    //imageInputのidを取得
    let id = $(this).attr('id');
    //選択したfile(画像)のオブジェクトを取得
    let file = this.files[0];
    // PC内にあるファイルをアプリケーションに非同期で読み込む
    let reader = new FileReader();
    //readAsDataURLで指定したFileオブジェクトを読み込む
    reader.readAsDataURL(file);
    //読み込み時に発火するイベント
    reader.onload = function() {
      // 直前に実行されたイベント(imageファイルの読み込み)を変数imageに代入
      let image = this.result;
      //htmlを作成
      let html = buildHTML(id,image);
      //<div class='prevImageBox>にプレビュー画像を追加
      $(prevImage).append(html);
      //画像が選択された状態(プレビュー画像表示中)だと、画像選択フォームを隠す
      $('.imageInput').hide();
    }
  });

プレビュー画像を削除する時の処理

// ==================================
  //   プレビュー画像を削除する場合の処理
  // ==================================
  $(document).on('click', '.delete-btn', function() {
    let id = $(this).attr('data-delete-id')
    //画像を消去
    $(this).parent().parent().parent().remove();
    //画像選択フォームの中身を空にする
    $('.imageInput').val("");
    //画像選択フォームを表示
    $('.imageInput').show();
  });

を分けて記述しております。

最後までご覧いただきありがとうございました。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?