【jQuery】ドラッグ&ドロップでファイル選択させる【ライブラリ不使用】

Frontend



ドラッグ&ドロップでファイル選択させ、かつ、プレビューを表示する機能をライブラリなし・jQueryで実装する方法を記します。

今回はひとつのinputにつき1ファイルのみアップロードできるように作成します。




HTML

input[type=file]とプレビューエリアを用意します。jQueryも読み込んでおきます。

アップロードアイコンに商用無料のフリーアイコンを使用しています。
使用アイコンのサイト:https://iconmonstr.com/

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<div class="drop-area">
    <label>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
            <path d="M19.479 10.092c-.212-3.951-3.473-7.092-7.479-7.092-4.005 0-7.267 3.141-7.479 7.092-2.57.463-4.521 2.706-4.521 5.408 0 3.037 2.463 5.5 5.5 5.5h13c3.037 0 5.5-2.463 5.5-5.5 0-2.702-1.951-4.945-4.521-5.408zm-7.479-1.092l4 4h-3v4h-2v-4h-3l4-4z"/>
        </svg>
        <input type="file" name="example" accept="image/jpeg, image/png" class="uploader">
        <div class="preview-area"></div>
    </label>
</div>







CSS

CSSで見た目を調整します。

.drop-area {
  border: 3px dashed #C8C8C8 !important;
  background-color: #F0F0F0 !important;
  border-radius: 5px;
  padding: 30px;
  text-align: center;
}
.drop-area label {
  width: 100%;
  display: inline-block;
}
.drop-area label:hover {
  cursor: pointer;
}
.drop-area label input {
  display: none;
}
.drop-area label svg {
  width: 50px;
  fill: currentColor;
  color: #909090;
}
.drop-area label .preview-area {
  width: 75%;
  margin: 15px auto;
  height: 120px;
}
.drop-area label .preview-area img {
  height: 100%;
  max-width: 100%;
  width: auto;
}




このような見た目になりました。

現時点ではまだドラッグ&ドロップはできません。





connaiconnai

jQuery

では、本題のドラッグ&ドロップ部分を作成していきます。

ドラッグ&ドロップでファイル選択させる

2行目でドロップされたファイルを取得してinput[type=file]にセットしております。
この時点で、ファイル選択された状態になります。

3行目は input[type=file] が変更されたことを伝えております。これは後ほどの画像プレビューのために行っております。

$(document).on('drop', '.drop-area' ,function (event) {
    $(this).find('.uploader')[0].files=event.originalEvent.dataTransfer.files
    $(this).find('.uploader').trigger('change')
})

ドロップされた画像をプレビューエリアに表示

先ほどの変更通知をキャッチしてイベントを発火しております。
input[type=file]からファイルを読み取りプレビューエリアにimgタグを投げるだけのシンプルな処理です。

$(document).on('change','.drop-area .uploader', function (e) {
    let thiss = $(this)
    let fileReader = new FileReader()
    fileReader.onload = (function () {
        let imgTag = `<img src='${fileReader.result}'>`
        thiss.closest(".drop-area").find(".preview-area").html(imgTag)
    })
    fileReader.readAsDataURL(e.target.files[0])
})

ドロップエリア以外のドロップ禁止

エリア外にドロップされた時の対応を入れておくと親切でしょう。
下記のように記述して、ドロップエリア以外のドロップはキャンセルします。

$(document).on('dragenter dragover drop', function (event) {
    event.stopPropagation()
    event.preventDefault()
})



下記のデモで動きをご確認頂けます。
ドロップエリアはいくつ増やしても問題なく動きます。
ドロップエリアを増やしたい時は、drop-areaクラスの要素ごとコピーして使用します。





ソースコード全文

最後にコードを全文載せておきます。

<style>
    .drop-area {
        border: 3px dashed #C8C8C8 !important;
        background-color: #F0F0F0 !important;
        border-radius: 5px;
        padding: 30px;
        text-align: center;
    }
    .drop-area label {
        width: 100%;
        display: inline-block;
    }
    .drop-area label:hover {
        cursor: pointer;
    }
    .drop-area label input {
        display: none;
    }
    .drop-area label svg {
        width: 50px;
        fill: currentColor;
        color: #909090;
    }
    .drop-area label .preview-area {
        width: 75%;
        margin: 15px auto;
        height: 200px;
    }
    .drop-area label .preview-area img {
        height: 100%;
        max-width: 100%;
        width: auto;
    }
</style>

<div class="drop-area">
    <label>
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
            <path d="M19.479 10.092c-.212-3.951-3.473-7.092-7.479-7.092-4.005 0-7.267 3.141-7.479 7.092-2.57.463-4.521 2.706-4.521 5.408 0 3.037 2.463 5.5 5.5 5.5h13c3.037 0 5.5-2.463 5.5-5.5 0-2.702-1.951-4.945-4.521-5.408zm-7.479-1.092l4 4h-3v4h-2v-4h-3l4-4z"/>
        </svg>
        <input type="file" name="example" accept="image/jpeg, image/png" class="uploader">
        <div class="preview-area"></div>
    </label>
</div>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script>
    $(window).on("load",function(){
        //ドラッグ&ドロップ時の操作
        $(document).on('drop', '.drop-area' ,function (event) {
            $(this).find('.uploader')[0].files=event.originalEvent.dataTransfer.files
            $(this).find('.uploader').trigger('change')
        })

        //ドロップエリア以外のドロップ禁止
        $(document).on('dragenter dragover drop', function (event) {
            event.stopPropagation()
            event.preventDefault()
        })

        //ファイルがアップロードされたらプレビューエリアに表示
        $(document).on('change','.drop-area .uploader',function(e) {
            let thiss = $(this)
            let fileReader = new FileReader()
            fileReader.onload = (function () {
                let imgTag = `<img src='${fileReader.result}'>`
                thiss.closest(".drop-area").find(".preview-area").html(imgTag)
            })
            fileReader.readAsDataURL(e.target.files[0])
        })
    })
</script>






以上、ドラッグ&ドロップでファイル選択させ、ドロップされた画像をプレビュー表示する方法でした。

コメント

タイトルとURLをコピーしました