现在我们可以把文件拖放到一个特殊的容器中,然后用XHR 2上传。一次很多。实时进度条等。非常酷的东西。例子。

但有时候我们并不想要那么酷。我想要的是拖放文件—许多一次—到一个标准的HTML文件输入:<input type=file multiple>。

这可能吗?是否有一些方法来“填充”文件输入与正确的文件名(?)从文件掉落?(出于文件系统安全原因,不能使用完整的文件路径。)

为什么?因为我想提交一份正常的表格。适用于所有浏览器和所有设备。拖放只是为了增强和简化用户体验的渐进式增强。带有标准文件输入(+多个属性)的标准表单将出现在那里。我想增加HTML5的增强功能。

编辑 我知道在某些浏览器中,有时(几乎总是)可以将文件放入文件输入本身。我知道Chrome通常会这样做,但有时它会失败,然后在当前页面加载文件(如果你正在填写表单,这是一个大失败)。我想愚弄&防浏览器。


当前回答

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

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

然而,你可以完全绕过表单控件,通过XHR上传(不确定是否支持):

https://developer.mozilla.org/en/Using_files_from_web_applications http://www.html5rocks.com/en/tutorials/file/xhr2/#toc-send-blob

你也可以在周围区域使用一个元素来取消Chrome中的删除事件,并防止默认的加载文件行为。

在Safari和Firefox中已经可以在输入中删除多个文件。

其他回答

这是我得出的结论。

使用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>

以下工作在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; // If you want to use some of the dropped files const dT = new DataTransfer(); dT.items.add(evt.dataTransfer.files[0]); dT.items.add(evt.dataTransfer.files[3]); fileInput.files = dT.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处理程序——这只是为了简洁起见。

我做了一个解。

$(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;文件输入是可见的,所以您可以看到发生了什么。

这是“DTHML”HTML5的实现方式。标准表单输入(正如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 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>

如果你能把整个窗口变成一个拖放区,那就更boss了,看看我如何检测进入和离开窗口的HTML5拖放事件,就像Gmail一样?

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

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

然而,你可以完全绕过表单控件,通过XHR上传(不确定是否支持):

https://developer.mozilla.org/en/Using_files_from_web_applications http://www.html5rocks.com/en/tutorials/file/xhr2/#toc-send-blob

你也可以在周围区域使用一个元素来取消Chrome中的删除事件,并防止默认的加载文件行为。

在Safari和Firefox中已经可以在输入中删除多个文件。