如何在页面上放置文件时设置文件输入值? [英] How to set file input value when dropping file on page?

查看:150
本文介绍了如何在页面上放置文件时设置文件输入值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做一个控制,你既可以选择一个文件在表单中提交,也可以在文件中放入一个文件来做同样的事情。我有类似的东西,它也会显示文件的预览,如果它是一个图像:

 < div class = preview-image-containerstyle =cursor:default;> 
< input type =filename =Fileid =Fileclass =form-controlaccept =image / *style =display:none;>
< div class =preview-image-dummy>< / div>< img class =preview-image-url>
< div class =preview-image-instructionstyle =background-color:inherit; cursor:default;>< i class =fa fa-4x fa-cloud-upload隐藏= 真 >< I> /;
< div class =preview-image-btn-browse btn btn-primary>选择文件< / div>
< p>或将其放在此处。< / p>
< / div>
< / div>

用户将文件放入预览图像容器中。该文件不是用AJAX提交的,用户需要提交包含更多数据的表单。



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



类似的问题,但没有正确的答案:


您可以设置以及在所有现代浏览器中获得 HTMLInputElement.files 的值。

源和浏览器兼容性,请参阅 MDN


blockquote>

Firefox 错误修正讨论线程有此 d emo你可以测试 ,这里是来源如果你想编辑它。如果此链接死亡,以供将来参考,我还将它作为可运行片段包含在下面:

  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:将文件放在此页面的任何位置;位置:固定;左:0;宽度:100%; top:0;身高:100%;显示: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 =viewportcontent =width = device-width> < link href =https://fonts.googleapis.com/css?family=Roboto:400,400i,700 =stylesheet> < title> JS Bin< / title>< / head>< body> < h1>将文件拖放到文件输入< / h1> < p>< small>在< a href =https://github.com/whatwg/html/issues/2861> WebKit和Blink< / a>中支持。要测试,请将一个或多个文件从操作系统拖放到此页面上。< / small>< / p> < p为H. < input type =file> < / body>< / html>  

hr>


重要提示:

您只能这样做如果您有一个现有的 FileList dataTransfer 对象,您可以将其设置为输入文件元素(作为setter方法不接受纯文本字符串)。



有关更多信息,请参阅Kaiido的答案:如何在FileList对象中设置File对象和length属性,其中的文件也在FormData对象中反映?






现在回答您的原始问题,它应该如此简单:



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


I'm attempting to make a control where you can both select a file to submit in the form and drop a file into it to do the same thing. I have something like this where it will also show a preview of the file if it's an image:

<div class="preview-image-container" style="cursor: default;">
    <input type="file" name="File" id="File" class="form-control" accept="image/*" style="display:none;">
    <div class="preview-image-dummy"></div><img class="preview-image-url">
    <div class="preview-image-instruction" style="background-color: inherit; cursor: default;"><i class="fa fa-4x fa-cloud-upload" aria-hidden="true"></i>
        <div class="preview-image-btn-browse btn btn-primary">Select file</div>
        <p>or drop it here.</p>
    </div>
</div>

The user drop the file in the preview-image-container. The file isn't submitted with AJAX, the user needs to submit the form which contain more data.

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.

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

Also not similar to drag drop images input file and preview before upload because I have already achieved drag-drop and preview action. My question is specific to the problem of having an empty file input when dropping the file in a parent container.


Here's a fiddle with MCVE. As you can see I am only interested in using jQuery or pure JavaScript without additional libraries.

Although dropzone.js could be used, it doesn't fit in my requirements and it would require a considerate amount of time to customize its look. Moreover, dropzone.js have certain configuration requirement that can't be met within my ASP.NET application.

解决方案

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


TL;DR: Yes, now you can!

*if you have a dataTransfer or FileList object

Previously, programmatically changing the files input[type=file] field was disabled due to legacy security vulnerabilities, which are fixed on modern browsers.

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

Relevant screenshot and text quoted from MDN:

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

For further information, see Kaiido's answer here: How to set File objects and length property at FileList object where the files are also reflected at FormData object?


Now to answer your original question, it should be as simple as this:

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

这篇关于如何在页面上放置文件时设置文件输入值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆