最近では、ファイルを特別なコンテナーにドラッグアンドドロップし、XHR 2でアップロードできます。ライブプログレスバーなど。非常にクールなもの。 ここの例
しかし、時にはそれほどクールにしたくないことがあります。私がしたいのは、ファイルをドラッグアンドドロップすることです-一度に多く-を標準のHTMLファイル入力に:<input type=file multiple>
。
それは可能ですか?ファイルドロップから正しいファイル名(?)でファイル入力を「埋める」方法はありますか? (ファイルシステムのセキュリティ上の理由から、完全なファイルパスは使用できません。)
理由?通常のフォームを送信したいので。すべてのブラウザおよびすべてのデバイス用。ドラッグアンドドロップは、UXを強化および簡素化するための単なる進歩的な強化です。標準ファイル入力(+ multiple
属性)を持つ標準フォームがそこにあります。 HTML5の拡張機能を追加したいと思います。
編集
私はsomeブラウザでできることを知っていますsometimes(ほとんどの場合、ファイルをファイル入力自体にドロップします。 Chromeが通常これを行うことを知っていますが、時々失敗し、現在のページにファイルをロードします(フォームに入力している場合は大きな失敗です)。私はそれを馬鹿にしたいと思います。
私はこれに対する解決策を作りました。
$(function () {
var dropZoneId = "drop-zone";
var buttonId = "clickHere";
var mouseOverClass = "mouse-over";
var dropZone = $("#" + dropZoneId);
var ooleft = dropZone.offset().left;
var ooright = dropZone.outerWidth() + ooleft;
var ootop = dropZone.offset().top;
var oobottom = dropZone.outerHeight() + ootop;
var inputFile = dropZone.find("input");
document.getElementById(dropZoneId).addEventListener("dragover", function (e) {
e.preventDefault();
e.stopPropagation();
dropZone.addClass(mouseOverClass);
var x = e.pageX;
var y = e.pageY;
if (!(x < ooleft || x > ooright || y < ootop || y > oobottom)) {
inputFile.offset({ top: y - 15, left: x - 100 });
} else {
inputFile.offset({ top: -400, left: -400 });
}
}, true);
if (buttonId != "") {
var clickZone = $("#" + buttonId);
var oleft = clickZone.offset().left;
var oright = clickZone.outerWidth() + oleft;
var otop = clickZone.offset().top;
var obottom = clickZone.outerHeight() + otop;
$("#" + buttonId).mousemove(function (e) {
var x = e.pageX;
var y = e.pageY;
if (!(x < oleft || x > oright || y < otop || y > obottom)) {
inputFile.offset({ top: y - 15, left: x - 160 });
} else {
inputFile.offset({ top: -400, left: -400 });
}
});
}
document.getElementById(dropZoneId).addEventListener("drop", function (e) {
$("#" + dropZoneId).removeClass(mouseOverClass);
}, true);
})
#drop-zone {
/*Sort of important*/
width: 300px;
/*Sort of important*/
height: 200px;
position:absolute;
left:50%;
top:100px;
margin-left:-150px;
border: 2px dashed rgba(0,0,0,.3);
border-radius: 20px;
font-family: Arial;
text-align: center;
position: relative;
line-height: 180px;
font-size: 20px;
color: rgba(0,0,0,.3);
}
#drop-zone input {
/*Important*/
position: absolute;
/*Important*/
cursor: pointer;
left: 0px;
top: 0px;
/*Important This is only comment out for demonstration purposes.
opacity:0; */
}
/*Important*/
#drop-zone.mouse-over {
border: 2px dashed rgba(0,0,0,.5);
color: rgba(0,0,0,.5);
}
/*If you dont want the button*/
#clickHere {
position: absolute;
cursor: pointer;
left: 50%;
top: 50%;
margin-left: -50px;
margin-top: 20px;
line-height: 26px;
color: white;
font-size: 12px;
width: 100px;
height: 26px;
border-radius: 4px;
background-color: #3b85c3;
}
#clickHere:hover {
background-color: #4499DD;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="drop-zone">
Drop files here...
<div id="clickHere">
or click here..
<input type="file" name="file" id="file" />
</div>
</div>
このメソッドのドラッグアンドドロップ機能は、Chrome、Firefox、およびSafariでのみ機能します。 (IE10で動作するかどうかはわかりません)が、他のブラウザーの場合、[またはここをクリックしてください]ボタンは正常に機能します。
入力フィールドは、ファイルをある領域にドラッグするときにマウスをたどるだけで、ボタンも追加しました。
不透明度のコメントを解除します:0;ファイル入力は表示されるだけなので、何が起こっているのかを見ることができます。
以下はChromeおよびFFで動作しますが、IE10 +をカバーするソリューションもまだ見つけていません。
// dragover and dragenter events need to have 'preventDefault' called
// in order for the 'drop' event to register.
// See: https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_operations#droptargets
dropContainer.ondragover = dropContainer.ondragenter = function(evt) {
evt.preventDefault();
};
dropContainer.ondrop = function(evt) {
// pretty simple -- but not for IE :(
fileInput.files = evt.dataTransfer.files;
evt.preventDefault();
};
<!DOCTYPE html>
<html>
<body>
<div id="dropContainer" style="border:1px solid black;height:100px;">
Drop Here
</div>
Should update here:
<input type="file" id="fileInput" />
</body>
</html>
おそらく、addEventListener
またはjQuery(など)を使用してevtハンドラーを登録することをお勧めします-これは簡潔にするためです。
これがHTML5の「DTHML」方法です。標準形式の入力(ISは、リカルドトマシが指摘したように読み取り専用)。次に、ファイルをドラッグすると、フォームに添付されます。この方法でアップロードされたファイルを受け入れるには、アクションページを変更する必要があります。
function readfiles(files) {
for (var i = 0; i < files.length; i++) {
document.getElementById('fileDragName').value = files[i].name
document.getElementById('fileDragSize').value = files[i].size
document.getElementById('fileDragType').value = files[i].type
reader = new FileReader();
reader.onload = function(event) {
document.getElementById('fileDragData').value = event.target.result;}
reader.readAsDataURL(files[i]);
}
}
var holder = document.getElementById('holder');
holder.ondragover = function () { this.className = 'hover'; return false; };
holder.ondragend = function () { this.className = ''; return false; };
holder.ondrop = function (e) {
this.className = '';
e.preventDefault();
readfiles(e.dataTransfer.files);
}
#holder.hover { border: 10px dashed #0c0 !important; }
<form method="post" action="http://example.com/">
<input type="file"><input id="fileDragName"><input id="fileDragSize"><input id="fileDragType"><input id="fileDragData">
<div id="holder" style="width:200px; height:200px; border: 10px dashed #ccc"></div>
</form>
ウィンドウ全体をドロップゾーンにすることができればさらに上司です。 Gmailのようにウィンドウに出入りするHTML5ドラッグイベントを検出するにはどうすればよいですか?
//----------App.js---------------------//
$(document).ready(function() {
var holder = document.getElementById('holder');
holder.ondragover = function () { this.className = 'hover'; return false; };
holder.ondrop = function (e) {
this.className = 'hidden';
e.preventDefault();
var file = e.dataTransfer.files[0];
var reader = new FileReader();
reader.onload = function (event) {
document.getElementById('image_droped').className='visible'
$('#image_droped').attr('src', event.target.result);
}
reader.readAsDataURL(file);
};
});
.holder_default {
width:500px;
height:180px;
border: 10px dashed #ccc;
}
#holder.hover {
width:400px;
height:180px;
border: 10px dashed #0c0 !important;
}
.hidden {
visibility: hidden;
}
.visible {
visibility: visible;
}
<!DOCTYPE html>
<html>
<head>
<title> HTML 5 </title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.js"></script>
</head>
<body>
<form method="post" action="http://example.com/">
<div id="holder" style="" id="holder" class="holder_default">
<img src="" id="image_droped" width="500" height="180" style="width:500px; height:180px; border: 10px dashed #7A97FC;" class=" hidden"/>
</div>
</form>
</body>
</html>
理論的には、<input/>
にオーバーレイする要素を追加し、そのdrop
イベントを使用してファイルをキャプチャし(File APIを使用)、入力files
配列に渡します。
ファイル入力が読み取り専用であることを除きます。これは古い問題です。
ただし、フォームコントロールを完全にバイパスし、XHRを介してアップロードすることはできます(そのサポートについてはわかりません)。
また、周囲の領域の要素を使用して、Chromeのドロップイベントをキャンセルし、ファイルをロードするデフォルトの動作を防ぐこともできます。
入力に複数のファイルをドロップすると、SafariとFirefoxですでに機能します。
私はChromeでいくつかのトリックが機能することを知っています:
ファイルをドロップゾーンにドロップすると、dataTransfer.files
オブジェクト、つまりFileList
タイプのオブジェクトが取得され、ドラッグしたすべてのファイルが含まれます。一方、<input type="file" />
要素にはプロパティfiles
があり、これは同じFileList
型オブジェクトです。
そのため、単にdataTransfer.files
オブジェクトをinput.files
プロパティに割り当てることができます。
CSSのみのソリューションの場合:
<div class="file-area">
<input type="file">
<div class="file-dummy">
<span class="default">Click to select a file, or drag it here</span>
<span class="success">Great, your file is selected</span>
</div>
</div>
.file-area {
width: 100%;
position: relative;
font-size: 18px;
}
.file-area input[type=file] {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
right: 0;
bottom: 0;
opacity: 0;
cursor: pointer;
}
.file-area .file-dummy {
width: 100%;
padding: 50px 30px;
border: 2px dashed #ccc;
background-color: #fff;
text-align: center;
transition: background 0.3s ease-in-out;
}
.file-area .file-dummy .success {
display: none;
}
.file-area:hover .file-dummy {
border: 2px dashed #1abc9c;
}
.file-area input[type=file]:valid + .file-dummy {
border-color: #1abc9c;
}
.file-area input[type=file]:valid + .file-dummy .success {
display: inline-block;
}
.file-area input[type=file]:valid + .file-dummy .default {
display: none;
}
2018年にこれを行うことを考えている人にとっては、ここに投稿されたすべての古いものよりもはるかに優れたシンプルなソリューションがあります。 Vanilla HTML、JavaScript、CSSだけで見栄えの良いドラッグアンドドロップボックスを作成できます。
(これまではChromeでのみ動作します)
HTMLから始めましょう。
<div>
<input type="file" name="file" id="file" class="file">
<span id="value"></span>
</div>
次に、スタイリングに進みます。
.file {
width: 400px;
height: 50px;
background: #171717;
padding: 4px;
border: 1px dashed #333;
position: relative;
cursor: pointer;
}
.file::before {
content: '';
position: absolute;
background: #171717;
font-size: 20px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 100%;
}
.file::after {
content: 'Drag & Drop';
position: absolute;
color: #808080;
font-size: 20px;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
これを実行した後、すでに問題なく見えます。しかし、実際にアップロードしたファイルを確認したいと思うので、JavaScriptを実行します。そのpfp値のスパンを覚えていますか?ここで、ファイル名を出力します。
let file = document.getElementById('file');
file.addEventListener('change', function() {
if(file && file.value) {
let val = file.files[0].name;
document.getElementById('value').innerHTML = "Selected" + val;
}
});
以上です。
@BjarkeCKによる素晴らしい仕事。 jqueryのメソッドとして使用するために、彼の作品にいくつかの変更を加えました。
$.fn.dropZone = function() {
var buttonId = "clickHere";
var mouseOverClass = "mouse-over";
var dropZone = this[0];
var $dropZone = $(dropZone);
var ooleft = $dropZone.offset().left;
var ooright = $dropZone.outerWidth() + ooleft;
var ootop = $dropZone.offset().top;
var oobottom = $dropZone.outerHeight() + ootop;
var inputFile = $dropZone.find("input[type='file']");
dropZone.addEventListener("dragleave", function() {
this.classList.remove(mouseOverClass);
});
dropZone.addEventListener("dragover", function(e) {
console.dir(e);
e.preventDefault();
e.stopPropagation();
this.classList.add(mouseOverClass);
var x = e.pageX;
var y = e.pageY;
if (!(x < ooleft || x > ooright || y < ootop || y > oobottom)) {
inputFile.offset({
top: y - 15,
left: x - 100
});
} else {
inputFile.offset({
top: -400,
left: -400
});
}
}, true);
dropZone.addEventListener("drop", function(e) {
this.classList.remove(mouseOverClass);
}, true);
}
$('#drop-zone').dropZone();
数年後、私は this library を構築して、HTML要素にファイルをドロップしました。
次のように使用できます
const Droppable = require('droppable');
const droppable = new Droppable({
element: document.querySelector('#my-droppable-element')
})
droppable.onFilesDropped((files) => {
console.log('Files were dropped:', files);
});
// Clean up when you're done!
droppable.destroy();
これは私が出てきたものです。
JqueryとHtmlを使用します。これにより、挿入ファイルに追加されます。
var dropzone = $('#dropzone')
dropzone.on('drag dragstart dragend dragover dragenter dragleave drop', function(e) {
e.preventDefault();
e.stopPropagation();
})
dropzone.on('dragover dragenter', function() {
$(this).addClass('is-dragover');
})
dropzone.on('dragleave dragend drop', function() {
$(this).removeClass('is-dragover');
})
dropzone.on('drop',function(e) {
var files = e.originalEvent.dataTransfer.files;
// Now select your file upload field
// $('input_field_file').prop('files',files)
});
input { margin: 15px 10px !important;}
.dropzone {
padding: 50px;
border: 2px dashed #060;
}
.dropzone.is-dragover {
background-color: #e6ecef;
}
.dragover {
bg-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div class="" draggable='true' style='padding: 20px'>
<div id='dropzone' class='dropzone'>
Drop Your File Here
</div>
</div>