将文件拖放到标准的html文件input中

现在我们可以把文件拖放到一个特殊的容器中,然后用XHR2上传它们。 现场进度条等非常酷的东西。 这里的例子。

但有时我们不想要那么多的冷静。 我想要的是将文件拖放到一个标准的HTML文件input<input type=file multiple>

那可能吗? 有没有什么办法来从文件下拉菜单中填入正确的文件名(?)? (完整的文件path不适用于文件系统安全原因。)

为什么? 因为我想提交一个正常的表格。 适用于所有浏览器和所有设备。 拖放只是渐进式的增强,以增强和简化用户体验。 标准文件input(+ multiple属性)的标准表单将在那里。 我想添加HTML5增强function。

编辑
我知道在某些浏览器中, 有时 (几乎总是)将文件放入文件input本身。 我知道Chrome通常会这样做,但有时会失败,然后将文件加载到当前页面(如果填写表单,则会导致严重失败)。 我想愚弄&浏览器它。

我为此做了一个解决scheme。

 $(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> 

这是“DTHML”HTML5的方式来做到这一点。 正常forms的input(只读作为Ricardo Tomasi指出)。 然后,如果文件被拖入,它被附加到表单。 这将需要修改操作页面来接受以这种方式上传的文件。

 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 document.getElementById('fileDragData').value = files[i].slice(); 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> 

以下在Chrome和FF的作品,但我还没有find一个覆盖IE10 +的解决scheme:

 // 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> 

理论上,你可以添加一个覆盖<input/>的元素,然后使用它的drop事件来捕获文件(使用File API),并将它们传递给inputfiles数组。

除了文件input是只读的 。 这是一个老问题。

但是,您可以完全绕过表单控件并通过XHR上传(不确定对此的支持):

您还可以使用周围区域的元素来取消Chrome中的放置事件,并防止加载文件的默认行为。

通过input删除多个文件已经可以在Safari和Firefox中使用。

 //----------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> 

我知道Chrome中的一些技巧。

将文件拖放到拖放区时,您将获得一个dataTransfer.files对象,即“FileList”types的对象,其中包含您拖动的所有文件。 同时,元素具有属性“文件”,即相同的“FileList”types的对象。

因此,您可以简单地将dataTransfer.files对象分配给input.files属性。

令人敬畏的@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(); 

工作小提琴

对于仅CSS解决scheme:

 <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; } 

https://codepen.io/Scribblerockerz/pen/qdWzJw修改;

你可以做什么,是显示一个文件的input,并与你的透明拖放区重叠,小心使用file[1]file[1] 。 {请务必在FORM标记中使用enctype="multipart/form-data" 。}

然后通过为文件2..number_of_filesdynamic创build更多的文件input,让drop-area处理额外的文件,一定要使用相同的基本名称,适当地填充value-attribute。

最后(前端)提交表格。


处理这个方法所需要的只是改变你的过程来处理一个文件数组。