勉強したことのメモ

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

  関連記事

画像をドラッグ&ドロップでアップロード

■2015/04/15追記 以下記事の方が新しくて詳しい。 http://tai ...

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

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

サムネイルをクリックすると拡大画像を表示できる「Lightbox」の利用方法

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

javascriptやjQueryで画像を書き換えても変わらない場合

けっこう前に画像をアップロードしてリアルタイムにプレビューする機能を作った時に、 ...

JSやjQueryで動的に追加した要素に対して「slick」でスライダーを実行する方法

外部サーバからAjax等で画像URLを取得したものをimgタグとしてページ内に描 ...