dav*_*ave 8 html javascript set
我有这种input类型"file",我想改变它的files列表.例:
<input type = "file" id = "fileinput" />
<script type = "text/javascript>
document.getElementById("fileinput").files = [10];
</script>
Run Code Online (Sandbox Code Playgroud)
问题是没有设置fileinput元素的files列表.我该怎么做?
FZs*_*FZs 54
确实不可能将本地文件添加到用户未请求的文件输入中;但是,有一种方法可以添加Blob或File对象到文件输入或从文件输入中删除特定文件。
要更改文件输入中的文件,您必须将 替换fileInput.files为另一个FileList对象。
问题是FileList对象是不可变的,并且没有暴露给 JS 的构造函数。
创建自定义的唯一方法FileList是滥用DataTransfer,这是一种设计用于使用拖放或通过剪贴板传输文件的 API。
所有主流浏览器都支持它,但 IE 不支持,并且仅从 Safari 14.1 版本开始支持。您可以在这里查看。
您可以DataTransfer通过调用不带参数的构造函数来创建对象:
const dataTransfer = new DataTransfer()
Run Code Online (Sandbox Code Playgroud)
创建的DataTransfer对象有一个files属性,幸运的是,该属性FileList包含该对象拥有的所有文件DataTransfer。
但那么如何将文件添加到呢DataTransfer?
每个DataTransfer都有一个DataTransferItemList与之关联的(可通过其items属性访问),该属性具有向DataTransfer.
要添加文件,您必须调用add它的方法并传递一个File对象。
就像这样:
dataTransfer.items.add(file)
Run Code Online (Sandbox Code Playgroud)
如果您的数据不在File对象中(例如,一个Blob或ArrayBuffer多个字节),则可以使用File构造函数,传递数据、文件名以及可选的具有type和lastModified属性的对象:
const file = new File([blob], 'file.txt', {type: 'text/plain', lastModified: modificationDate})
Run Code Online (Sandbox Code Playgroud)
所以,总而言之,我们有这样的东西:
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 --------+
Run Code Online (Sandbox Code Playgroud)
我确信现在这很混乱,但让我们看一些代码!
如果您想创建一个名为hello.txtcontains的文件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.filesRun Code Online (Sandbox Code Playgroud)
<p>Notice that the file input contains "hello.txt" now: </p>
<input type="file" id="fileInput" />Run Code Online (Sandbox Code Playgroud)
但是,您如何编辑输入中已有的文件列表,而不是替换文件?
DataTransferDataTransfer另请参阅我关于该主题的回答。
为此,我创建了一对函数,用于从Files 数组中获取和设置文件列表,因此可以在数组上执行转换,而不是使用DataTransfers 执行复杂的操作:
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
}
Run Code Online (Sandbox Code Playgroud)
你可以像这样使用它们:
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)
})Run Code Online (Sandbox Code Playgroud)
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>Run Code Online (Sandbox Code Playgroud)
odr*_*drm 15
出于安全原因,浏览器会阻止javascript更改将要上传的文件:只有用户才能通过用户界面选择文件.这是为了防止恶意脚本上传/etc/passwd,例如,在用户不知道的情况下.
一个例外是在表单上调用"reset"将清除文件或文件列表,但您永远不能以编程方式添加.