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

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

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

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

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


当前回答

对于没有任何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

其他回答

这是我得出的结论。

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

简单明了。您不需要创建一个新的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;">

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

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

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

理论上,您可以添加一个覆盖<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中已经可以在输入中删除多个文件。

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