我有一个文件上传器,当从图像预览中删除图像时,该图像将从
FileList
。这是通过创建一个新数组并从新数组中删除目标(已删除)元素,然后使用
dataTranser()
将其设置为“file”输入元素的FileList。所有这些都可以正常工作。
问题
我遇到的问题是,如果在提交之前通过filepicker输入元素添加了更多的文件(无论是否删除了任何文件),即使图像预览在显示的图像数量和特定图像方面是正确的,上传/提交的文件始终是用最新选择添加的文件。如果只选择了一组文件,这当然是可以的,但如果在提交之前添加了额外的图像/文件,则第二组将覆盖第一组(尽管图像在图像预览中仍然正确显示)。
要查看问题,如果您通过代码示例中的“浏览”按钮选择要上传的文件,然后第二次单击“浏览”键添加更多图像,您就会明白我的意思。
问题
我如何获得它,以便在添加第二个文件选择时,这些文件会添加到现有阵列中,而不会覆盖它?
注1:
为了使代码更简单,我设置了它,以便在单击特定图像预览时删除图像,而不是通过“删除图像”按钮。
注2:
用于处理表单的后端代码是PHP,但我没有包括它,因为它不是问题的一部分。
代码笔:
https://codepen.io/thechewy/pen/wvjOdEq
let attachFiles = document.getElementById("attach-files");
let previewWrapper = document.getElementById("show-selected-images");
let form = document.getElementById("upload-images-form");
attachFiles.addEventListener("change", (e) => {
[...e.target.files].forEach(showFiles);
});
function showFiles(file) {
let previewImage = new Image();
previewImage.dataset.name = file.name;
previewImage.classList.add("img");
previewImage.src = URL.createObjectURL(file);
previewWrapper.append(previewImage); // append preview image
// -- remove the image preview visually and change FileList
document.querySelectorAll(".img").forEach((i) => {
i.addEventListener("click", (e) => {
const transfer = new DataTransfer();
const name = e.target.dataset.name;
for (const file of attachFiles.files) {
if (file.name !== name) {
transfer.items.add(file);
}
}
attachFiles.files = transfer.files;
//remove image preview element when image is clicked
e.target.remove();
});
});
}
form {
padding: 1rem 2rem;
width: 50%;
border: 1px solid;
}
input,
button {
display: block;
margin: 2rem 0;
}
.img {
width: 200px;
height: 200px;
object-fit: cover;
margin: 0 1rem;
}
img:hover {
cursor: pointer;
}
<form enctype="multipart/form-data" method="post" id="upload-images-form">
<input id="attach-files" type="file" name="attach-files[]" multiple>
<button name="submit" id="submit">SUBMIT</button>
<div id="show-selected-images"></div>
</form>