原版JS多图像上传在删除文件时不起作用,在手动选择文件时起作用



我正在使用一个基于此脚本的脚本,允许用户向表单中添加多个图像。

表单有多个其他输入,多图像选择是其中的一部分

如果我使用"单击此处"手动"选择文件,则文件将与表单提交一起发送。但是,如果用户将它们放在"dropzone"中,则不会将它们与表单一起发送。我如何确保它们与表单一同发送?

let dropBox = document.getElementById('dropBox');
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(evt => {
dropBox.addEventListener(evt, prevDefault, false);
});
function prevDefault(e) {
e.preventDefault();
e.stopPropagation();
}
['dragenter', 'dragover'].forEach(evt => {
dropBox.addEventListener(evt, hover, false);
});
['dragleave', 'drop'].forEach(evt => {
dropBox.addEventListener(evt, unhover, false);
});
function hover(e) {
dropBox.classList.add('!bg-lime-100', 'border-lime-300');
}
function unhover(e) {
dropBox.classList.remove('!bg-lime-100', 'border-lime-300');
}
dropBox.addEventListener('drop', mngDrop, false);
function mngDrop(e) {
let dataTrans = e.dataTransfer;
let files = dataTrans.files;
filesManager(files);
}
function filesManager(files) {
files = [...files];
files.forEach(previewFile);
}
function previewFile(file) {
if (!file.type.match(/image.*/)) {
return alert('Only JPG, JPEG and PNG files are allowed');
}
let fReader = new FileReader();
let gallery = document.getElementById('gallery');
fReader.readAsDataURL(file);
fReader.onloadend = function() {
let wrap = document.createElement('div');
let img = document.createElement('img');
img.src = fReader.result;
img.classList.add('rounded-lg');
let imgCapt = document.createElement('p');
let fSize = Math.round((file.size / 1024 / 1024) * 10) / 10 + ' MB';
imgCapt.innerHTML = `<span class="text-md font-bold tracking-tight">${fSize}</span>`;
gallery.appendChild(wrap).appendChild(img);
gallery.appendChild(wrap).appendChild(imgCapt);
}
}
<form method="post" action="..." enctype="multipart/form-data">
<input type="text" name="name">
<input type="text" name="example">
<input type="text" name="etc">
<div id="dropBox" class="border-2 border-dashed bg-white border-slate-300 rounded-lg md:p-5 p-10 text-center">
<p class="mb-2 mt-4">Drag and drop your images here, or</p>
<input type="file" name="photos[]" id="imgUpload" multiple accept="image/*" onchange="filesManager(this.files)" class="hidden">
<label for="imgUpload" class="block mt-4 font-bold cursor-pointer"><u>Click here</u> to select from your computer</label>
<div id="gallery" class="mt-4 grid grid-cols-2 md:grid-cols-3 gap-4"></div>
</div>
</form>

我试着在previewFile函数中添加这个,但不起作用:

let dropBox = document.getElementById('dropBox');
let formData = new FormData(dropBox[0]);
formData.append('photos', file);

<input type="file">元素是只读输入。无法将文件分配给他们。出于安全原因,用户输入是将客户端计算机上的文件附加到表单上所必需的;浏览"或";选择文件"按钮提供用户输入。

在拖放交互的情况下,创建一个FormData对象:

const photoFormData = new FormData();

并且使用forEach():将每个文件CCD_

files.forEach((file, idx) => {
photoFormData.append(`photos[${idx}]`, file);
}); 

files数组中文件的索引(idx(用于区分FormData对象中的每个文件。

当用户提交表单时,使用提交addEventListener()将保存文件的FormData对象发布到使用fetch():发布表单的位置

document.querySelector('form').addEventListener('submit', function ({target}) {
fetch(target.action, {
method: 'put',
body: photoFormData
})
.then(result => { console.log('Success:', result); })
.catch(error => { console.error('Error:', error); });
});

可以在filesManager()函数中追加文件:

function filesManager(files) {
files = [...files];
files.forEach((file, idx) => {
photoFormData.append(`photos[${idx}]`, file);
}); 
files.forEach(previewFile);
}

let dropBox = document.getElementById('dropBox');
const photoFormData = new FormData();
document.querySelector('form').addEventListener('submit', function ({target}) {
fetch(target.action, {
method: 'put',
body: photoFormData
})
.then(result => { console.log('Success:', result); })
.catch(error => { console.error('Error:', error); });
});
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(evt => {
dropBox.addEventListener(evt, prevDefault, false);
});
function prevDefault(e) {
e.preventDefault();
e.stopPropagation();
}
['dragenter', 'dragover'].forEach(evt => {
dropBox.addEventListener(evt, hover, false);
});
['dragleave', 'drop'].forEach(evt => {
dropBox.addEventListener(evt, unhover, false);
});
function hover(e) {
dropBox.classList.add('!bg-lime-100', 'border-lime-300');
}
function unhover(e) {
dropBox.classList.remove('!bg-lime-100', 'border-lime-300');
}
dropBox.addEventListener('drop', mngDrop, false);
function mngDrop(e) {
let dataTrans = e.dataTransfer;
let files = dataTrans.files;
filesManager(files);
}
function filesManager(files) {
files = [...files];
files.forEach((file, idx) => {
photoFormData.append(`photos[${idx}]`, file);
}); 
files.forEach(previewFile);
}
function previewFile(file) {
if (!file.type.match(/image.*/)) {
return alert('Only JPG, JPEG and PNG files are allowed');
}
let fReader = new FileReader();
let gallery = document.getElementById('gallery');
fReader.readAsDataURL(file);
fReader.onloadend = function() {
let wrap = document.createElement('div');
let img = document.createElement('img');
img.src = fReader.result;
img.classList.add('rounded-lg');
let imgCapt = document.createElement('p');
let fSize = Math.round((file.size / 1024 / 1024) * 10) / 10 + ' MB';
imgCapt.innerHTML = `<span class="text-md font-bold tracking-tight">${fSize}</span>`;
gallery.appendChild(wrap).appendChild(img);
gallery.appendChild(wrap).appendChild(imgCapt);
}
}

最新更新