FileList,推送新的图片文件,access/remove by index
FileList, push new image files, access/remove by index
此输入元素允许拍摄多张图片,例如,如果我 select 2 张图片,我得到:FileList {0: File, 1: File, length: 2}。然后,如果我再次 select 例如 1 张图片,我会得到另一个 FileList:FileList {0: File, length: 1}。有机会把这个新图像推送到第一个 FileList 吗?并且可以通过他的索引删除 FileList 的图像?提前致谢。
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
console.log(files);
for (var i = 0; i < files.length; i++) {
console.log(files[i]);
}
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
if (!f.type.match('image.*')) {
continue;
}
let reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
.thumb {
height: 75px;
border: 1px solid #000;
margin: 10px 5px 0 0;
}
<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>
您 select 只下载了一个文件 3 次。
要获取多个文件,您需要 select 从文件选择器中一次调用它们。
这将取决于 OS,但在我的 macOS 上,我可以通过按 cmd 键(可能是 ctrl 在其他 OSes) 上单击我想要 select.
的项目
这是您可以使用 FormData.
获得所需结果的方法
您可以更改代码以获得所需的外观和功能。
总结以下代码的作用:
- 创建一个新的
FormData
实例
- 接受来自文件输入的文件
- 将文件附加到在步骤 1 中创建的
FormData
的名为 file-${index}
的字段中
- 为每个
File
创建一个 FileReader
实例
FileReader
读取文件内容,returns data: URL 将文件数据表示为 base64 编码字符串。
- 创建一个
span
元素并向其附加一个 img
元素,其中第 5 步的文件内容为 src
- 将
click
侦听器附加到 span
,因此当用户单击图像时,相应的文件将从步骤 1 的 FormData
中删除,span
将从 DOM
中删除
- 当用户使用
sendFiles
函数作为点击处理程序点击 submit files
按钮时,FormData
将使用 Fetch API 作为请求正文发送到后端。
您可以在 sunbmit 按钮下看到附加到 FormData
的文件列表及其相应的表单字段名称和原始文件名,作为 ul
使用生成的listFiles
函数
const formData = new FormData();
// to be used for files field names of FormData
let index = 0;
// for listing current files
const listFiles = () => {
const list = document.createElement("ul");
Array.from(formData.entries()).forEach((entry) => {
const item = document.createElement("li");
item.innerHTML = entry[0] + ": " + entry[1].name;
list.appendChild(item);
});
document.querySelector("#fileList").innerHTML = list.innerHTML;
};
// for sending files to the backend
const sendFiles = () => {
fetch("/upload/path", {
body: formData,
method: "POST",
})
.then((response) => response.json()) // If the response is in JSON format
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error(error);
});
};
// for outputting fileReader output and file for FormData
// it needs to be async because of async nature of fileReader onload event so we can keep FormData and FileReader in sync using index
const readFile = (file) => {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = (event) => {
const theFile = event.target;
return resolve([file, theFile]);
};
fileReader.readAsDataURL(file);
});
};
const handleFileSelect = async (event) => {
var files = event.target.files;
for (const file of files) {
if (file.type.match("image.*")) {
const [fileData, theFile] = await readFile(file);
const id = `file-${index}`;
formData.append(id, fileData);
const span = document.createElement("span");
const img = document.createElement("img");
img.src = theFile.result;
img.alt = "Image thumb";
img.title = escape(fileData.name);
img.className = "thumb";
span.appendChild(img);
// for removing the thumbnail and its linked file from FormData
span.addEventListener("click", () => {
formData.delete(id);
// listing current files appended to FormData after removing this thumbnail
listFiles();
span.remove();
});
index++;
document.getElementById("list").insertBefore(span, null);
}
}
// list files after adding new file/files
listFiles();
};
document.getElementById("files").addEventListener("change", handleFileSelect, false);
.thumb {
height: 75px;
border: 1px solid #000;
margin: 10px 5px 0 0;
}
<input type="file" id="files" name="files[]" multiple />
<br />
<h3>click on images to remove them</h3>
<output id="list"></output>
<br /><br /><br />
<button onclick="sendFiles()">submit Files</button>
<ul id="fileList"></ul>
此输入元素允许拍摄多张图片,例如,如果我 select 2 张图片,我得到:FileList {0: File, 1: File, length: 2}。然后,如果我再次 select 例如 1 张图片,我会得到另一个 FileList:FileList {0: File, length: 1}。有机会把这个新图像推送到第一个 FileList 吗?并且可以通过他的索引删除 FileList 的图像?提前致谢。
function handleFileSelect(evt) {
var files = evt.target.files; // FileList object
console.log(files);
for (var i = 0; i < files.length; i++) {
console.log(files[i]);
}
// Loop through the FileList and render image files as thumbnails.
for (var i = 0, f; f = files[i]; i++) {
if (!f.type.match('image.*')) {
continue;
}
let reader = new FileReader();
reader.onload = (function(theFile) {
return function(e) {
// Render thumbnail.
var span = document.createElement('span');
span.innerHTML = ['<img class="thumb" src="', e.target.result,
'" title="', escape(theFile.name), '"/>'].join('');
document.getElementById('list').insertBefore(span, null);
};
})(f);
reader.readAsDataURL(f);
}
}
document.getElementById('files').addEventListener('change', handleFileSelect, false);
.thumb {
height: 75px;
border: 1px solid #000;
margin: 10px 5px 0 0;
}
<input type="file" id="files" name="files[]" multiple />
<output id="list"></output>
您 select 只下载了一个文件 3 次。
要获取多个文件,您需要 select 从文件选择器中一次调用它们。
这将取决于 OS,但在我的 macOS 上,我可以通过按 cmd 键(可能是 ctrl 在其他 OSes) 上单击我想要 select.
这是您可以使用 FormData.
获得所需结果的方法您可以更改代码以获得所需的外观和功能。
总结以下代码的作用:
- 创建一个新的
FormData
实例 - 接受来自文件输入的文件
- 将文件附加到在步骤 1 中创建的
FormData
的名为file-${index}
的字段中 - 为每个
File
创建一个 FileReader
读取文件内容,returns data: URL 将文件数据表示为 base64 编码字符串。- 创建一个
span
元素并向其附加一个img
元素,其中第 5 步的文件内容为src
- 将
click
侦听器附加到span
,因此当用户单击图像时,相应的文件将从步骤 1 的FormData
中删除,span
将从DOM
中删除
- 当用户使用
sendFiles
函数作为点击处理程序点击submit files
按钮时,FormData
将使用 Fetch API 作为请求正文发送到后端。
FileReader
实例
您可以在 sunbmit 按钮下看到附加到 FormData
的文件列表及其相应的表单字段名称和原始文件名,作为 ul
使用生成的listFiles
函数
const formData = new FormData();
// to be used for files field names of FormData
let index = 0;
// for listing current files
const listFiles = () => {
const list = document.createElement("ul");
Array.from(formData.entries()).forEach((entry) => {
const item = document.createElement("li");
item.innerHTML = entry[0] + ": " + entry[1].name;
list.appendChild(item);
});
document.querySelector("#fileList").innerHTML = list.innerHTML;
};
// for sending files to the backend
const sendFiles = () => {
fetch("/upload/path", {
body: formData,
method: "POST",
})
.then((response) => response.json()) // If the response is in JSON format
.then((data) => {
console.log(data);
})
.catch((error) => {
console.error(error);
});
};
// for outputting fileReader output and file for FormData
// it needs to be async because of async nature of fileReader onload event so we can keep FormData and FileReader in sync using index
const readFile = (file) => {
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = (event) => {
const theFile = event.target;
return resolve([file, theFile]);
};
fileReader.readAsDataURL(file);
});
};
const handleFileSelect = async (event) => {
var files = event.target.files;
for (const file of files) {
if (file.type.match("image.*")) {
const [fileData, theFile] = await readFile(file);
const id = `file-${index}`;
formData.append(id, fileData);
const span = document.createElement("span");
const img = document.createElement("img");
img.src = theFile.result;
img.alt = "Image thumb";
img.title = escape(fileData.name);
img.className = "thumb";
span.appendChild(img);
// for removing the thumbnail and its linked file from FormData
span.addEventListener("click", () => {
formData.delete(id);
// listing current files appended to FormData after removing this thumbnail
listFiles();
span.remove();
});
index++;
document.getElementById("list").insertBefore(span, null);
}
}
// list files after adding new file/files
listFiles();
};
document.getElementById("files").addEventListener("change", handleFileSelect, false);
.thumb {
height: 75px;
border: 1px solid #000;
margin: 10px 5px 0 0;
}
<input type="file" id="files" name="files[]" multiple />
<br />
<h3>click on images to remove them</h3>
<output id="list"></output>
<br /><br /><br />
<button onclick="sendFiles()">submit Files</button>
<ul id="fileList"></ul>