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

<div class="preview-image-container">

  <input type="file" name="File" id="File" accept="image/*" 
         class="image-url form-control" style="display:none;" />

  <div class="preview-image-dummy"></div><img class="preview-image-url" />
  <div class="preview-image-instruction">
    <div class="preview-image-btn-browse btn btn-primary">Select file</div>
    <p>or drop it here.</p>
  </div>

</div>

Here's a fiddle with MCVE.

用户将文件放入preview-image-container.文件不是用AJAX提交的,用户需要提交包含更多数据的表单.

For security reasons, we aren't allowed to change the value of the input file with JavaScript. However, I know that the default input file support droppable and there's a bunch of websites that let us select files by dropping them in the form so my guess is that there's a way to do it.

As you can see from the MCVE, I am only interested in using jQuery or pure JavaScript without additional libraries.

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


There's a similar question but does not have a proper answer:
How to set file object into input file in the form in HTML?

也不类似于drag drop images input file and preview before upload,因为我已经实现了拖放和预览操作.My question is specific to the problem of having an empty file input when dropping the file in a parent container.

推荐答案

Disclaimer: Correct as of December 2017 and for modern browsers only.


TL;DR: Yes, now you can!

*如果您有数据传输或文件列表对象

Previously,以编程方式更改文件input[type=file]字段已被禁用,因为传统的安全漏洞已在现代浏览器上修复.

The last of the major browsers (Firefox), has recently enabled us to set the files for the input file field. According to testing done by W3C, it seems that you can already do this on Google Chrome!

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

enter image description here

You can set as well as get the value of HTMLInputElement.files in all modern browsers.
Source and browser compatibility, see MDN

The Firefox bugfix discussion thread has this demo you can test it out on, and here's the source if you want to edit it. For future reference in case this link dies, I will also include it as a runnable snippet below:

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;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
      <link href="https://fonts.googleapis.com/css?family=Roboto:400,400i,700" rel="stylesheet"> 

  <title>JS Bin</title>
</head>
<body>
  
  <h1>Drag and drop files into file input</h1>
  
  <p><small>Supported in <a href="https://github.com/whatwg/html/issues/2861">WebKit and Blink</a>. To test, drag and drop one or more files from your operating system onto this page.</small></p>
  
  <p>
    <input type="file">
  </p>

</body>
</html>


Important note:

You can only do this if you have an existing FileList OR dataTransfer object that you are able to set to the input file element (as the setter method DOES NOT accept plain text strings).

有关更多信息,请参见Kaiido的答案:How to set File objects and length property at FileList object where the files are also reflected at FormData object?


现在来回答你原来的问题,应该是这样简单的:

document.querySelector('.preview-image-instruction')
    .addEventListener('drop', (ev) => {
        ev.preventDefault();
        document.querySelector('.image-url').files = ev.dataTransfer.files;
    });

Jquery相关问答推荐

通过 Ajax POST 将按钮值从 HTML 发送到 Flask 时出现空数据

第一次单击后,Ajax addEventListener 停止工作

Jquery $(this) 子 Select 器

禁用提交按钮,直到所有字段都有值

JQuery通过类名获取所有元素

.trigger() 与 .click() 中的 jQuery 优势/差异

jQuery Keypress 箭头键

根据属性'data-sort'对jQuery中的div进行排序?

如何在 Backbone.js - Backbone.sync 或 jQuery.ajax 中保存整个集合?

如何使用 jQuery 进行带命名空间的 XML 解析

删除索引后的所有项目

如何更改 dropzone.js 中的默认文本?

通过 AJAX 和 jQuery 使用 HTML5 文件上传

使用 jQuery 按字母顺序对选项元素进行排序

Rails 无法正确解码来自 jQuery 的 JSON(数组变成带有整数键的散列)

如何通过javascript数组中的键和值查找对象的索引

如何使用 jQuery 格式化电话号码

jQuery位置href

调整浏览器大小时如何自动居中 jQuery UI 对话框?

将变量的值复制到另一个