在Firefox中设置FileInput的FileList [英] Set FileList of FileInput in Firefox

查看:124
本文介绍了在Firefox中设置FileInput的FileList的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这两个示例均可在 Chrome Opera 中使用,但在 Firefox 56.0 中失败。

Both examples work in Chrome and Opera, but fail in Firefox 56.0.

我想设置表单的文件输入文件 FileList。[ Codepen ]

I want to set the files FileList of a form's file input.[Codepen]

<form>
  <input type="file" id="input1" multiple>
  <br>
  <input type="file" id="input2" multiple>
</form>



JAVASCRIPT



JAVASCRIPT

var input1 = document.getElementById("input1");
var input2 = document.getElementById("input2");

input1.onchange = function () {
  console.log(input1.files);
  input2.files = input1.files;
};

在Chrome和Opera上,选择第一个输入中的文件也会改变第二个。在Firefox中,第二个输入不会改变,即使 filelist 在控制台的输出中显示正确。

On Chrome and Opera, selecting files in the first input, will also change the second. In Firefox, the second input doesn't change, even though the filelist appears to be correct in the console's output.

总体目标是创建一个拖放上传界面。

原型

The overall goal is to create a drag-drop upload interface.
Prototype here.

推荐答案

能够以编程方式将FileList设置为 input.files 属性三个月前已被添加为 PR到规范,即使webkit允许这样做多年。 Firefox 已在其下一个稳定版本中获得了补丁,57和Edge 可能仍在努力(I没有帐户可以查看进度。) 它似乎现在已经登陆Edge了。

The ability to set a FileList as the input.files property programmatically has been added as an PR to the specs three months ago, even if webkit allow this for years. Firefox has landed a patch in its next stable version, 57 and Edge is probably still working on it (I don't have an account to see the progress).It seems it has now landed in Edge too.

主要此功能的用例是允许 DataTransfer.files 从例如拖放事件或粘贴事件添加到< input> 字段。因此,只允许使用FileList(并且 null 来清除输入)。

The main use case for this feature is to allow DataTransfer.files from e.g a drag&drop event or a paste one to be added to an <input> field. As such, only a FileList is allowed (and null to clear the input).

因此,在问题正文中暴露的情况下,我真的没有看到在两个< input>之间使用此功能的重点; 字段。

So in the case exposed in the body of your question, I don't really see the point of using this feature between two <input> fields.

如果要在内存中选择FileList,可以随时将其转换为文件数组。

If you want to keep in memory selected FileList, you can always convert it as an Array of files.

如果您希望以后可以在< form> 中移动填充的输入,则可以直接使用inputElement和DOM方法。

If you want to be able to move your filled input in a <form> later on, you can do it directly with the inputElement and DOM methods.

如果您需要解决此新功能所利用的限制,您可以随时使用DataTransfer的文件填充FormData,并通过xhr发送此FormData,而不是使用默认的HTML表单方法。

And if you need to workaround the limitations this new feature leverages, you can always fill an FormData with the DataTransfer's files and send this FormData through xhr instead of using the default HTML form method.

由于我第一次错过了真正的用例,在codepen中,这是一个可能的实现解决您遇到的拖放问题,即使在不支持此新功能的旧版浏览器上也是如此。

And Since I first missed the real use-case, in the codepen, here is an possible implementation to workaround the drag&drop issue you are facing, even on older browsers that didn't support this new feature.

这使用了dropZone中的隐藏输入,它将捕获直接删除文件。

This uses an hidden input in the dropZone, which will catch the dropped files directly.

// called when the input hidden in the dropZone changes
function handleDroppedChange(evt) {
  this.removeEventListener('drop', handleDroppedChange); // only once
  // create a new hidden input
  var clone = this.cloneNode();
  clone.addEventListener('change', handleDroppedChange);
  clone.addEventListener('change', handleBasicChange);
  this.parentNode.insertBefore(clone, this);
  // replace the visible one with the current hidden one
  var form = document.querySelector('form');
  var previous = form.querySelector('input[type=file]');
  form.insertBefore(this, previous);
  form.removeChild(previous);
  this.id = previous.id; // for the <label>
}
// add first listeners
var hiddenTarget = dropzone.querySelector('input[type="file"]');
hiddenTarget.addEventListener('change', handleDroppedChange);
hiddenTarget.addEventListener('change', handleBasicChange);
file_input.addEventListener('change', handleBasicChange);
// handle drop over enter leave as usual on the parent
dropzone.ondragover = dropzone.ondragenter = function(evt) {
  evt.preventDefault();
  dropzone.className = "drag";
};

dropzone.ondragleave = function(evt) {
  evt.preventDefault();
  dropzone.className = "";
};

dropzone.ondrop = function(evt) {
  dropzone.className = "";
  console.log("drop");
};

// will trigger for any kind of changes (dropped or manual)
function handleBasicChange(evt) {
  var file_names = Array.prototype.map.call(this.files, function(f){return f.name;});
  label.innerHTML = "Changed " + file_names.join('<br>');
  // start upload process
};

#dropzone {
  display: inline-block;
  padding: 25px;
  border: 8px dashed #b11;
  position: relative;
}

#dropzone.drag {
  border-color: #f74;
}
#dropzone>input{
  opacity: 0;
  position: absolute;
  height: 100%;
  width: 100%;
  left: 0;
  top: 0;

/* below rules avoid clicks on hidden input */
  pointer-events: none; 
  }
#dropzone.drag>input{
  pointer-events: all;
  }

<form>
  <input type="file" id="file_input" multiple>
</form><br><br>

<div id="dropzone">
  <label id="label" for="file_input">Drop here.</label>
  <!-- we use an hidden file input to catch the dropped files -->
  <input type="file" multiple>
</div>

这篇关于在Firefox中设置FileInput的FileList的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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