根据主输入类型=“文件”(多个)元素创建多个input type =“file”元素及其对应的值(FileList)

时间:2018-01-15 04:44:45

标签: javascript jquery fileapi

我有这个代码,我从多输入文件类型

循环到文件

$(function(){

$('#main-input').change(function(){
  var files = $('#main-input')[0].files;
  for (var i = 0, f; f = files[i]; i++) {

      alert(files[i].name);

  }
});

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="file" id="main-input" multiple>

我想要实现的是克隆主输入(#main-input)并根据循环文件给出一个值(文件)。有什么想法,建议吗?或者这甚至可能吗?

1 个答案:

答案 0 :(得分:4)

是的,要求是可能的。您需要为每个FileList对象创建一个新的File,然后将.files元素的<input type="file">属性设置为FileList,其中填充{{1}对象。

下面的代码在Chromium 62+和Firefox 57+上返回相同的结果,请参阅@Kaiido对SafariEdge的评估的评论。

File
// FileList.js
class FileList {
  constructor(...items) {
    // flatten rest parameter
    items = [].concat(...items);
    // check if every element of array is an instance of `File`
    if (items.length && !items.every(file => file instanceof File)) {
      throw new TypeError("expected argument to FileList is File or array of File objects");
    }
    // use `ClipboardEvent("").clipboardData` for Firefox, which returns `null` at Chromium
    // we just need the `DataTransfer` instance referenced by `.clipboardData`
    const dt = new ClipboardEvent("").clipboardData || new DataTransfer();
    // add `File` objects to `DataTransfer` `.items`
    for (let file of items) {
      dt.items.add(file)
    }
    return dt.files;
  }
}

document.querySelector("input[type=file]")
.onchange = e => {
  for (let file of e.target.files) {
    const input = document.createElement("input");
    input.type = "file";
    input.files = new FileList(file);
    document.body.appendChild(input);
  }
}

<input type="file" multiple>
// FileList.js
function _FileList(items) {
    // flatten rest parameter
    items = [].concat.apply([], [items]);
    // check if every element of array is an instance of `File`
    if (items.length 
        && !items.every(function(file) { 
             return file instanceof File})) {
      throw new TypeError("expected argument to FileList is File or array of File objects");
    }
    // use `ClipboardEvent("").clipboardData` for Firefox, which returns `null` at Chromium
    // we just need the `DataTransfer` instance referenced by `.clipboardData`
    var dt = new ClipboardEvent("").clipboardData || new DataTransfer();
    // add `File` objects to `DataTransfer` `.items`
    for (var i = 0; i < items.length; i++) {
      dt.items.add(items[i])
    }
    return dt.files;
}

document.querySelector("input[type=file]")
.onchange = function(e) {
  for (var i = 0; i < e.target.files.length; i++) {
    var input = document.createElement("input");
    input.type = "file";
    input.files = new _FileList(e.target.files[i]);
    document.body.appendChild(input);
  }
}