将文件拖放到标准 html 文件输入中

新手上路,请多包涵

如今,我们可以将文件拖放到一个特殊的容器中,然后使用 XHR 2 上传它们。一次很多。带有实时进度条等。非常酷的东西。 这里的例子。

但有时我们不想要那么酷。我想要将文件(一次很多)拖放 到标准 HTML 文件输入中<input type=file multiple>

那可能吗?有没有办法用正确的文件名(?)从文件拖放中“填充”文件输入? (出于文件系统安全原因,完整文件路径不可用。)

为什么? 因为我想提交一个普通的表格。适用于所有浏览器和所有设备。拖放只是渐进式增强,以增强和简化 UX。带有标准文件输入(+ multiple 属性)的标准表单将在那里。我想添加 HTML5 增强功能。

编辑

我知道在 某些 浏览器中,您 有时(几乎总是)可以将文件放入文件输入本身。我知道 Chrome 通常会这样做,但有时它会失败,然后将文件加载到当前页面中(如果你正在填写表格,那就大失败了)。我想愚弄和浏览器证明它。

原文由 Rudie 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 526
2 个回答

以下适用于 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 处理程序——这只是为了简洁起见。

原文由 jlb 发布,翻译遵循 CC BY-SA 4.0 许可协议

我为此做了一个解决方案。

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

原文由 BjarkeCK 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题