我有:
<input type="file" id="f" name="f" onchange="c()" multiple />
每次用户选择文件时,我都会通过将f.files
的每个元素推入数组来构建所有选定文件的列表:
var Files = [];
function c() {
for (var i=0;i<this.files.length;i++) {
Files.push(this.files[i]);
};
}
在表单提交时,f.files
仅包含上次选择操作中的项目,因此我将需要用我累积的f.files
个项目的列表来更新FileList
:
const upload=document.getElementById("f");
upload.files = files;
但是第二行给出:
未捕获的TypeError:无法在'HTMLInputElement'上设置'files'属性:提供的值不是'FileList'类型。
我为它分配一个数组并不高兴。如何从我之前收集的FileList
个元素的列表中构造一个FileList
对象?
侧面问题:我认为Javascript使用动态类型。为什么在这里抱怨类型错误?
答案 0 :(得分:9)
就像你说的
您只能使用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)
<input type="file" id="fileInput" multiple />
执行此操作将触发更改事件,因此您可能需要打开和关闭更改事件侦听器
答案 1 :(得分:1)
您无法修改文件列表,但是可以使用DataTransfer对象创建一个文件列表。
let list = new DataTransfer();
let file = new File(["content"], "filename.jpg");
list.items.add(file);
let myFileList = list.files;
然后可以将其设置为DOM节点的文件属性:
fileInput.files = myFileList;
如果愿意,可以遍历旧的FileList,将文件复制到新的FileList。
答案 2 :(得分:-1)
您应该使用本机类FileList。 您可以在MDN
中找到完整的文档和示例。