是否可以更新FileList?

Old*_*zer 7 javascript

我有:

<input type="file" id="f" name="f" onchange="c()" multiple />
Run Code Online (Sandbox Code Playgroud)

每次用户选择文件时,我都会通过将每个元素压f.files入数组来构建所有选定文件的列表:

var Files = [];
function c() {
  for (var i=0;i<this.files.length;i++) {
    Files.push(this.files[i]);
  };
}
Run Code Online (Sandbox Code Playgroud)

在提交表单时,f.files仅包含上次选择操作中的项目,因此我将需要更新自己累积f.filesFileList项目列表:

const upload=document.getElementById("f");
upload.files = files;
Run Code Online (Sandbox Code Playgroud)

但是第二行给出:

未捕获到的TypeError:无法在'HTMLInputElement'上设置'files'属性:提供的值不是'FileList'类型的。

我为它分配一个数组并不高兴。如何FileListFileList先前收集的元素列表中构造一个对象?

附带问题:我认为Javascript使用动态类型。为什么在这里抱怨类型错误?

End*_*ess 14

就像你说的

您只能使用FileList设置文件,不幸的是FileList是不可构造的或不可更改的,但是有一种方法可以使文件列表全面

// Used for creating a new FileList in a round-about way
function FileListItem(a) {
  a = [].slice.call(Array.isArray(a) ? a : arguments)
  for (var c, b = c = a.length, d = !0; b-- && d;) d = a[b] instanceof File
  if (!d) throw new TypeError("expected argument to FileList is File or array of File objects")
  for (b = (new ClipboardEvent("")).clipboardData || new DataTransfer; c--;) b.items.add(a[c])
  return b.files
}

var files = [
  new File(['content'], 'sample1.txt'),
  new File(['abc'], 'sample2.txt')
];

fileInput.files = new FileListItem(files)
Run Code Online (Sandbox Code Playgroud)
<input type="file" id="fileInput" multiple />
Run Code Online (Sandbox Code Playgroud)

这样做将触发更改事件,因此您可能需要打开和关闭更改事件侦听器

  • 顺便说一句,这在 iOS Safari 上不起作用。我还没有解决。 (3认同)

sup*_*ary 10

You can't modify a Filelist, but you can create a new one using a DataTransfer object, and if you wish you can copy your data into it to create a duplicate with the specific change you want to make.

let list = new DataTransfer();
let file = new File(["content"], "filename.jpg");
list.items.add(file);

let myFileList = list.files;
Run Code Online (Sandbox Code Playgroud)

You can then set it as the file attribute of the DOM node:

fileInput.files = myFileList;
Run Code Online (Sandbox Code Playgroud)

If you wished, you could iterate over your old FileList, copying files to the new one.

  • Mac 和 ios 上的 Safari 现在都支持 `DataTransfer()`!!!https://caniuse.com/mdn-api_datatransfer_datatransfer 自 2021 年 4 月起生效 (5认同)
  • DataTransfer() 不支持 iOS (4认同)
  • `DataTransfer()` not supported in safari as well. Safari is becoming like IE. (4认同)