LoginSignup
0

posted at

updated at

Laravel8 jQuery 画像動的表示

初めに

この記事では、画像選択時にその場で選択した画像を表示させる方法をご紹介します!

Image from Gyazo

実装

今回は以下のように実装してみました。
CSSはTailwindCSSを使用してます。

・add.blade.php(画像選択のビュー)

<div class="flex justify-center md:px-20 xl:px-20">
    <label class="block px-12 py-2 rounded-md bg-gray-300">
        <p class="text-center">画像を選択</p>
        <input id="img_upload" type="file" accept="image/*" name="image" value="{{old('image')}}" class="hidden -ml-12" onchange=" previewImage(this)">
        @error('image')
        <p class="w-44 text-red-500 text-sm">{{$message}}</p>
        @enderror
    </label>
</div>

<div class="flex justify-center">
    <label class="block w-44">
        <img id="preview" class="h-48 w-full" src="https://zaikokanri.s3.ap-northeast-1.amazonaws.com/SQBzGcvgGvOftMYGWG85i2DBuXaONl6FbiW9uwoA.jpg">
    </label>

    <script>
        function previewImage(obj) {
            var fileReader = new FileReader(); 
            fileReader.onload = (function() {
                document.getElementById('preview').src = fileReader.result;
            });
            fileReader.readAsDataURL(obj.files[0]);
        }
    </script>
</div>

・app.blade.php
add.blade.phpは親元であるapp.blade.phpを継承している構成になっていますが、一様app.blade.phpの

部分は以下のような感じになってます。

ここに関しては今回のjQuery導入に合わせて何か読み込んだりといったことは特にしていないです。

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>@yield('title')</title>

    <!-- Fonts -->
    <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap">

    <!-- Styles -->
    <link rel="stylesheet" href="{{ mix('css/app.css') }}">

    @livewireStyles

    <!-- Scripts -->
    <script src="{{ mix('js/app.js') }}" defer></script>

</head>

jQuery部分の説明

<script>
    function previewImage(obj) {
        var fileReader = new FileReader();
        fileReader.onload = (function() {
        document.getElementById('preview').src = fileReader.result;
    });
            fileReader.readAsDataURL(obj.files[0]);
        }

        $(function() {
            $(document).on('change', '#receipt', function() {
                $('#preview').addClass('img-thumbnail');
            });
        });
</script>

var fileReader = new FileReader();
FileReaderオブジェクトでユーザーのコンピュータに保存されているファイルの内容を非同期に読み取る。
それをvarで定義したfileReader変数に格納。

document.getElementById('preview').src = fileReader.result;
document.getElementById('preview').src
画像選択ボタン部分で指定したid=previewかつ画像要素を特定

fileReader.result;
読み込んだファイルの内容を返す。また、こちらはデータの読み取り操作が完了した後でしかファイルの内容を返しません。読み取りができてない場合はnullとなります。

fileReader.readAsDataURL(obj.files[0]);
ファイルのデータを表すbase64エンコーディングされたdata:URLの文字列を格納。

readAsDataURLメソッド
指定されたfile型の内容を読み込む。
読み込み操作が終了するとreadyStateがDONEとなりloadendが発生。このとき、result属性にはファイルのデータを表すbase64エンコーディングされたdata:URLの文字列が格納される。

readState
XMLHttpRequestのプロパティで、通信状態を表す数値を返す。

DONE
成功・失敗に関わらず通信を終了した状態。

load
loadendイベントは、リクエストが正常に完了した場合afterloadまたは失敗した場合afterabortまたはerrorが発生。

base64
64進数を意味する言葉で、すべてのデータをアルファベットa〜z, A〜Zと数字0〜9、一部の記号+,/の64文字で表すエンコード方式。
データ長を揃えるためにパディング(データを一定の長さに整形するため前後に挿入される無意味なデータ)として末尾に記号の=を使用。

おまけ

下記のようにしてあげると画像周りに角丸の枠線を付け加えることができます!

$(function() {
 $(document).on('change', '#receipt', function() {
     $('#preview').addClass('img-thumbnail');
 });
});

$(document).on('change', '#img_upload', function(){}
changeイベントが発生したとき、function{}に書いた処理を実行する。

change
フォーム(input要素)や選択メニュー(select要素)、テキストエリア(textarea要素)にてユーザーの操作によって値が変更されたときに発生するイベント。

$('#preview').addClass('img-thumbnail');
#previewに対して``img-thumbnailクラス属性を追加

img-thumbnailクラス
bootstrapのクラスで、画像の周りに角丸の枠線が追加される。

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
What you can do with signing up
0