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

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

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

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

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


当前回答

对于那些想在2018年这样做的人来说,我有一个比这里发布的所有旧东西更好更简单的解决方案。你可以用普通的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-value跨度吗?这就是我们打印文件名的地方。

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

就是这样。

其他回答

我知道在Chrome中有一些技巧:

当你把文件放到drop zone时,你会得到一个dataTransfer。files对象,这是一个FileList类型的对象,它包含您拖动的所有文件。同时,<input type="file" />元素具有属性文件,即相同的FileList类型对象。

因此,您可以简单地分配dataTransfer。文件对象指向输入。文件属性。

您可以做的是显示一个文件输入,并用透明的下拉区域覆盖它,注意使用像文件[1]这样的名称。{确保在FORM标签中有enctype="multipart/ FORM -data"}

然后让下拉区域通过动态地为文件2创建更多的文件输入来处理额外的文件。Number_of_files,请确保使用相同的基名,适当地填充value-属性。

最后(前端)提交表单。


处理这个方法所需要做的就是修改过程来处理一个文件数组。

对于没有任何JS的本地解决方案:

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

<style>
    .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;
    }
</style>

改编自https://codepen.io/Scribblerockerz/pen/qdWzJw

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

工作小提琴

使用它吧。(Html - Css);)

<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">    
<style>
    .upload-container {
        position: relative;
    }
    .upload-container input {
        border: 1px solid #92b0b3;
        background: #f1f1f1;
        outline: 2px dashed #92b0b3;
        outline-offset: -10px;
        padding: 100px 0px 100px 250px;
        text-align: center !important;
        width: 500px;
    }
    .upload-container input:hover {
        background: #ddd;
    }   
    .upload-container:before {
        position: absolute;
        bottom: 50px;
        left: 245px;
        content: " (or) Drag and Drop files here. ";
        color: #3f8188;
        font-weight: 900;
    }   
    .upload-btn {
        margin-left: 300px;
        padding: 7px 20px;
    }        
</style>
<script>
             
    function uploadFiles() {
        var files = document.getElementById('file_upload').files;
        if(files.length==0){
            alert("Please first choose or drop any file(s)...");
            return;
        }
        var filenames="";
        for(var i=0;i<files.length;i++){
            filenames+=files[i].name+"\n";
        }
    }
            
</script>
</head>
<body>
    <div class="upload-container">
        <input type="file" id="file_upload" multiple />
    </div>
    <br>
    <button class="upload-btn" onclick="uploadFiles()">Submit</button>  
</body>
</html>