ドラッグ&ドロップでファイル選択させ、かつ、プレビューを表示する機能をライブラリなし・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;
}
このような見た目になりました。
現時点ではまだドラッグ&ドロップはできません。
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>
以上、ドラッグ&ドロップでファイル選択させ、ドロップされた画像をプレビュー表示する方法でした。
コメント