gpt4 book ai didi

javascript - 如何以编程方式更改文件输入的 FileList?

转载 作者:太空狗 更新时间:2023-10-29 13:41:21 26 4
gpt4 key购买 nike

我有一个类型为 "file"input,我想更改它的 files 列表。示例:

<input type = "file" id = "fileinput" />
<script type = "text/javascript">
document.getElementById("fileinput").files = [10];
</script>

问题是 fileinput 元素的 files 列表没有设置。我该怎么做?

最佳答案

在用户未请求的文件输入中添加本地文件确实不可能的;但是,一种方法可以向特定文件添加BlobFile 对象删除特定文件 来自文件输入。


要更改文件输入中的文件,您必须将 fileInput.files 替换为另一个 FileList 对象。

问题是 FileList 对象是不可变 并且没有构造函数 暴露给 JS。

创建自定义 FileList 的唯一方法是滥用 DataTransfer ,这是一种专为使用拖放或通过剪贴板传输文件而设计的 API。

所有主流浏览器都支持它,但 IE 不支持,Safari 14.1 之后才支持。你可以检查它 here

您可以通过调用不带参数的构造函数来创建 DataTransfer 对象:

const dataTransfer = new DataTransfer()

创建的 DataTransfer 对象有一个 files 属性,幸运的是,它是一个包含 DataTransfer 拥有的所有文件的 FileList

但是如何将文件添加到DataTransfer呢?

每个 DataTransfer 都有一个与之关联的 DataTransferItemList(可通过其 items 属性访问),它具有向 DataTransfer 添加(和删除)项的方法.

要添加文件,您必须对其调用 add 方法并传递一个 File 对象。

像这样:

dataTransfer.items.add(file)

如果您的数据不在File 对象中(例如字节的BlobArrayBuffer),您可以使用File constructor ,将数据、文件名和可选的具有 typelastModified 属性的对象传递给它:

const file = new File([blob], 'file.txt', {type: 'text/plain', lastModified: modificationDate})

所以,总而言之,我们有这样的东西:

new DataTransfer()
|
v
DataTransfer
| |
| +--[ .items ]---> DataTransferItemList
| |
+--[ .files ]------+ +---[ .add(file) ]---> DataTransferItem
| ^
v |
+--[ .files ] <-- FileList |
| +--- File <--- new File([data], filename, options)
| ^
| |
<input type="file"> Blob ----------+---------------------+
ArrayBuffer ---+
string --------+

我敢肯定这现在很困惑,但让我们看一些代码!

如果您想创建一个名为 hello.txt 的文件,其中包含 Hello world! 并将输入设置为包含此文件,您可以按照以下方法进行操作:

const fileInput = document.getElementById('fileInput')

const dataTransfer = new DataTransfer()

const file = new File(['Hello world!'], 'hello.txt', {type: 'text/plain'})

dataTransfer.items.add(file)

fileInput.files = dataTransfer.files
<p>Notice that the file input contains "hello.txt" now: </p>
<input type="file" id="fileInput" />

但是除了替换文件之外,您如何编辑输入中已有的文件列表?

  1. 创建一个DataTransfer
  2. 添加输入中的所有现有文件,但要删除的文件除外
  3. 添加你要添加的文件
  4. 将输入中的文件替换为 DataTransfer
  5. 中的文件

另请参阅有关该主题的 this answer of mine

为此,我创建了一对函数,用于从 File 的数组中获取和设置文件列表,因此可以在数组上执行转换,而不用做复杂的事情数据传输:

function getFiles(input){
const files = new Array(input.files.length)
for(let i = 0; i < input.files.length; i++)
files[i] = input.files.item(i)
return files
}

function setFiles(input, files){
const dataTransfer = new DataTransfer()
for(const file of files)
dataTransfer.items.add(file)
input.files = dataTransfer.files
}

您可以像这样使用它们:

function getFiles(input){
const files = new Array(input.files.length)
for(let i = 0; i < input.files.length; i++)
files[i] = input.files.item(i)
return files
}

function setFiles(input, files){
const dataTransfer = new DataTransfer()
for(const file of files)
dataTransfer.items.add(file)
input.files = dataTransfer.files
}

const fileInput = document.querySelector('#fileInput')

document.querySelector('#removeFirst').addEventListener('click', () => {
const files = getFiles(fileInput)

files.shift()

setFiles(fileInput, files)
})
document.querySelector('#removeLastModified').addEventListener('click', () => {
const files = getFiles(fileInput)

let latest = 0, latestIndex
for(let i = 0; i < files.length; i++)
if(files[i].lastModified > latest){
latest = files[i].lastModified
latestIndex = i
}
files.splice(latestIndex, 1)

setFiles(fileInput, files)
})
document.querySelector('#addFile').addEventListener('click', () => {
const files = getFiles(fileInput)

const newFiles = getFiles(document.querySelector('#addFileInput'))
files.push(...newFiles)

setFiles(fileInput, files)
})
document.querySelector('#addRandomHello').addEventListener('click', () => {
const files = getFiles(fileInput)

const newFile = new File(['Hello world!'], 'hello.txt', {type: 'text/plain'})
const index = Math.floor(Math.random() * (files.length + 1))
files.splice(index, 0, newFile)

setFiles(fileInput, files)
})
Hint: hover over the file input to see the list of all files in it <br>
<input type="file" id="fileInput" multiple ><br><br>
<button id="removeFirst">Remove first file</button><br>
<button id="removeLastModified">Remove latest modified file</button><br>
<button id="addFile">Append file from this input</button> <input type="file" id="addFileInput" /><br>
<button id="addRandomHello">Add a hello.txt file to a random place</button><br>

关于javascript - 如何以编程方式更改文件输入的 FileList?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5632629/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com