勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

ライブラリ等を使用せずファイルをドラッグ&ドロップでアップロードする方法

formにドラッグ&ドロップでファイルをアップロードする機能を実装する場合、Dropzone.jsを使用する方法を以前にメモした。ただそのメモは10年近く前のものなのでもっと良い方法があるんじゃないかと調べたところライブラリを使用せず実装できる方法があった。以下に実装方法をメモ。

 

やりたいこと

以下を実装したい。

  • フォームにinput="file"を用意し、そちらをドラッグ&ドロップでファイル選択できるようにしたい
  • ドラッグ&ドロップエリアをクリックすると通常のinput="file"と同様、ファイルを選択できるようにしたい
  • ファイル選択時は視覚的に分かりやすいようプレビュー表示させたい

 

準備

ファイルのアップロード処理はclass.upload.phpを使いたいので過去記事を参照の上、インストールしておく。

 

ソースコード

フォーム側(index.php)

<html lang="ja">
<head>
    <meta charset="utf-8">
</head>
<style>
#drop_zone {
    border: 5px solid blue;
    width: 200px;
    height: 100px;
}
#drop_zone input {
    display: block;
    opacity: 0;
}
</style>
<body>
    <form action="upload.php" method="post" enctype="multipart/form-data">
        <div id="preview"></div>
        <div id="drop_zone">
            ファイルをドラッグ&ドロップで選択してください。
            <input type="file" name="file" id="file">
        </div>
        <input type="submit" name="submit" value="送信">
    </form>
    <script type="text/javascript" src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <script>
    $(function(){
        $(`#file`).on('change', function(){

            //画像取得
            const file = $(this).prop('files')[0];
            const type = file.type;

            //画像かどうかチェック
            if( !type.match(/^image/) ){
                alert('画像を選択してください');
                $(this).val('');
                return false;
            }

            //FileReaderオブジェクトのインスタンス化
            let reader = new FileReader();

            //画像の読み込み
            reader.readAsDataURL(file);

            //読み込み失敗時
            reader.onerror = function(){
                alert('ファイル読み取りに失敗しました');
                $(this).val('');
                return false;
            }

            //画像を表示
            reader.onload = function() {
                $(`#preview`).html(`<img src="${reader.result}" style="width:100px;">`)
            }
        });
    });
    </script>
</body>
</html>

アップロード側(upload.php)

<?php
require_once 'class.upload.php';

$file = $_FILES['file'];
$lang = 'ja_JP';

$handle = new \Verot\Upload\Upload($file, $lang);

if( $handle->uploaded ){

    //ファイル名の変更
    $handle->file_new_name_body = date('YmdHis');

    //同一ファイル名の場合は上書き
    $handle->file_overwrite = true;

    //アスペクト比はそのままで横幅を300pxにリサイズ
    $handle->image_resize = true;
    $handle->image_x = 300;
    $handle->image_ratio = true;

    $handle->image_convert = 'webp';

    //アップロードするディレクトリ指定
    $handle->process('./file/');
    if( $handle->processed ){
        //成功処理
        echo 'success';

    }else{
        //エラー処理
        echo $handle->error;
    }

}else{
    //エラー処理
    echo $handle->error;
}

解説

初めて知ったんだけどinput="file"自体がドラッグ&ドロップ可能みたい。そのためドラッグ&ドロップもしくは通常のファイル選択後「$(`#file`).on('change', function(){」にてサムネイルを表示するという形になっている。

サムネイル表示に関して詳しくは過去記事参照。

 

所感

今回の方法以外にもHTML Drag and Drop APIというHTMLのWeb APIがあるらしいので後日試してみたいところ。

 

参考サイト

https://blog.kimizuka.org/entry/2020/08/11/080000

 - jQuery JavaScript

  関連記事

jQueryで画像が存在すれば表示、なければノーイメージ画像を表示

やりたかった事は以下の通り。 ・画像のURLはcode.jpgみたいになってる ...

Dropzone.jsを使って画像をドラッグ&ドロップでアップロードする方法

画像を複数枚ドラッグ&ドロップでアップロードしたかった。だいぶ前にDro ...

jQueryのプラグインで簡単にイメージスライダーを作成(bxslider)

画像のスライダーを作る時に便利なプラグインであるbxslider。簡単に使えるし ...

画像をサムネイル⇔クリックで拡大(lightbox)

画像をサムネイル表示してクリックしたら大きく表示する というのがlightbox ...

Ajaxで画像のアップロード(jquery.upload)

業務中に画像の選択後、アップロードボタンを押して画像のアップ、 その後フォームの ...