在页面上删除文件时如何设置文件输入值?

我正在尝试创建一个控件,您可以在其中选择要在表单中提交的文件,并将文件放入其中以执行相同的操作。 我有这样的东西,如果它是一个图像,它也会显示该文件的预览:

Select file

or drop it here.

这是MCVE的小提琴 。

用户将文件放在preview-image-container 。 该文件未通过AJAX提交,用户需要提交包含更多数据的表单。

出于安全原因,我们不允许使用JavaScript更改输入文件的值。 但是,我知道默认输入文件支持droppable,并且有一堆网站让我们通过将它们放在表单中来选择文件,所以我的猜测是有一种方法可以做到这一点。

正如您从MCVE中看到的,我只对使用jQuery或纯JavaScript而不使用其他库感兴趣。

尽管可以使用dropzone.js ,但它不符合我的要求,并且需要花费大量的时间来定制其外观。 此外, dropzone.js具有某些在我的ASP.NET应用程序中无法满足的配置要求。


有一个类似的问题,但没有一个正确的答案:
如何在HTML格式的表单中将文件对象设置为输入文件?

因为我已经实现了拖放和预览操作,所以在上传之前也没有类似于拖放图像输入文件和预览 。 我的问题是特定于在父容器中删除文件时输入空文件的问题。

免责声明:截至2017年12月正确,仅适用于现代浏览器。


TL; DR:是的,现在你可以!

*如果您有dataTransfer或FileList对象

以前 ,由于旧的安全漏洞(在现代浏览器上已修复),以编程方式更改文件input[type=file]字段已被禁用。

最后一个主流浏览器(Firefox)最近使我们能够为输入文件字段设置文件。 根据W3C测试 ,您似乎已经可以在Google Chrome上执行此操作了!

MDN引用的相关屏幕截图和文字:

在此处输入图像描述

您可以在所有现代浏览器中设置和获取HTMLInputElement.files的值。
源和浏览器兼容性,请参阅MDN

Firefox错误修正讨论线程有这个演示,您可以测试它, 如果您想编辑它 ,这里是源 。 如果此链接死亡以供将来参考,我还将其包含在下面的runnable片段中:

 let target = document.documentElement; let body = document.body; let fileInput = document.querySelector('input'); target.addEventListener('dragover', (e) => { e.preventDefault(); body.classList.add('dragging'); }); target.addEventListener('dragleave', () => { body.classList.remove('dragging'); }); target.addEventListener('drop', (e) => { e.preventDefault(); body.classList.remove('dragging'); fileInput.files = e.dataTransfer.files; }); 
 body { font-family: Roboto, sans-serif; } body.dragging::before { content: "Drop the file(s) anywhere on this page"; position: fixed; left: 0; width: 100%; top: 0; height: 100%; display: flex; justify-content: center; align-items: center; font-size: 1.5em; background-color: rgba(255, 255, 0, .3); pointer-events: none; } button, input { font-family: inherit; } a { color: blue; } 
       JS Bin   

Drag and drop files into file input

Supported in WebKit and Blink. To test, drag and drop one or more files from your operating system onto this page.