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

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

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

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

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


当前回答

//----------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:150px; border: 3px dashed #ccc; } #holder.hover { width:400px; height:150px; border: 3px 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="200" style="border: 3px dashed #7A97FC;" class=" hidden"/> </div> </form> </body> </html>

其他回答

几年后,我已经构建了这个库来将文件放入任何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();

简单明了。您不需要创建一个新的FormData或执行Ajax来发送图像。您可以在输入字段中放置拖拽文件。

Osx用户:也许在Osx中你需要最大化你的浏览器来拖动文件。为什么?idk。

$dropzone.ondrop = function (e) {
    e.preventDefault();
    input.files = e.dataTransfer.files;
}

var $dropzone = document.querySelector('.dropzone'); var input = document.getElementById('file-upload'); $dropzone.ondragover = function (e) { e.preventDefault(); this.classList.add('dragover'); }; $dropzone.ondragleave = function (e) { e.preventDefault(); this.classList.remove('dragover'); }; $dropzone.ondrop = function (e) { e.preventDefault(); this.classList.remove('dragover'); input.files = e.dataTransfer.files; } .dropzone { padding: 10px; border: 1px dashed black; } .dropzone.dragover { background-color: rgba(0, 0, 0, .3); } <div class="dropzone">Drop here</div> <input type="file" id="file-upload" style="display:none;">

@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();

工作小提琴

//----------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:150px; border: 3px dashed #ccc; } #holder.hover { width:400px; height:150px; border: 3px 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="200" style="border: 3px dashed #7A97FC;" class=" hidden"/> </div> </form> </body> </html>

这是“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一样?