我在 HTML 和 JavaScript 下面有这段代码。有一段 PHP 代码正在成功将所有内容发送到数据库,无需显示。
<form action="" method="post" enctype="multipart/form-data">
<label for="titulo">Título:</label>
<input type="text" id="titulo" name="titulo" required><br><br>
<label for="descricao">Descrição:</label><br>
<textarea id="descricao" name="descricao" required></textarea><br><br>
<div id="preview"></div>
<label for="imagens">Imagens:</label>
<input type="file" id="imagens" name="imagens[]" multiple accept="image/*">
<small>(Você pode selecionar várias imagens segurando a tecla Ctrl)</small><br><br>
<input type="submit" value="Cadastrar Anúncio">
</form>
<script>
(function() {
function previewImages() {
var input = document.getElementById("imagens");
var preview = document.getElementById("preview");
preview.innerHTML = ""; // Limpa a prévia de imagens anterior
if (input.files && input.files.length > 0) {
for (var i = 0; i < input.files.length; i++) {
var reader = new FileReader();
reader.onload = function(e) {
var imageContainer = document.createElement("div");
imageContainer.className = "image-container";
var image = document.createElement("img");
image.src = e.target.result;
image.style.maxWidth = "100px"; // Define a largura máxima das miniaturas
imageContainer.appendChild(image);
var deleteButton = document.createElement("button");
deleteButton.innerText = "Deletar";
deleteButton.className = "delete-button";
deleteButton.addEventListener("click", function() {
// Função para deletar a imagem
imageContainer.parentNode.removeChild(imageContainer);
// Desanexar a imagem do input file
//input.value = "";
});
imageContainer.appendChild(deleteButton);
preview.appendChild(imageContainer);
};
reader.readAsDataURL(input.files[i]);
}
}
}
// Adicione o evento onchange ao campo de entrada de arquivo fora das tags HTML
var imagensInput = document.getElementById("imagens");
imagensInput.onchange = previewImages;
})();
</script>
问题是基于以下事实:当我单击图像缩略图下方出现的“删除”按钮时,我认为它实际上删除了缩略图并似乎删除了临时文件。
这是已经显示的代码的独立部分,负责删除图像缩略图。
var deleteButton = document.createElement("button");
deleteButton.innerText = "Deletar";
deleteButton.className = "delete-button";
deleteButton.addEventListener("click", function() {
// Função para deletar a imagem
imageContainer.parentNode.removeChild(imageContainer);
// Desanexar a imagem do input file
//input.value = "";
});
imageContainer.appendChild(deleteButton);
preview.appendChild(imageContainer);
但是,附加到输入的所有图像(为多个文件制作)都会发送到数据库,包括通过按钮删除的图像。
正确的做法是保留通过按钮删除的图像并防止其发送到数据库。
我已经阅读了其他线程中提供此解决方案的答案:
reader.onload = function(e) {
//rest of code omitted
input.value = "";
});
但这不起作用,因为当您插入这行代码时,所有图像都会被删除,而不是唯一选择的图像。
如何解决?
这是一个很长的示例,但我的想法是维护所选文件的数组(此处为 Map 对象)。可以从该数组中添加文件(用于添加一个或多个文件的文件选择器)或删除文件(您的删除按钮)。最后(在提交事件上)您可以创建一个 formData 对象并添加数组中所有表单字段和文件的值。让 JavaScript 通过以 formData 对象作为主体的获取请求来处理提交事件。
var images = new Map();
const preview = document.getElementById('preview');
document.forms.form01.addEventListener('submit', e => {
e.preventDefault();
let data = new FormData(e.target);
data.delete('images');
images.forEach((file, id) => {
let blob = dataURItoBlob(file.src);
data.append('images[]', blob, file.name);
});
fetch('post.php', {
method: 'POST',
body: data
});
});
document.forms.form01.images.addEventListener('input', e => {
let input = e.target;
[...input.files].forEach(file => {
let reader = new FileReader();
reader.fileinfo = {
name: file.name,
lastModified: file.lastModified,
size: file.size,
type: file.type
};
reader.addEventListener('load', e => {
let file = e.target.fileinfo;
file.src = e.target.result;
images.set(`id${file.lastModified}${file.size}`, file);
previewImages();
});
reader.readAsDataURL(file);
});
input.value = "";
});
document.forms.form01.addEventListener('click', e => {
switch (e.target.name) {
case 'delete':
images.delete(e.target.value);
previewImages();
break;
case 'browse':
e.target.form.images.click();
break;
}
});
function previewImages() {
// add images to the preview div if not already there
images.forEach((file, id) => {
if (!preview.querySelector(`#${id}`)) {
let imageContainer = document.createElement("div");
imageContainer.className = "image-container";
imageContainer.id = id;
let image = document.createElement("img");
image.src = file.src;
image.style.maxWidth = "100px"; // Define a largura máxima das miniaturas
imageContainer.appendChild(image);
var deleteButton = document.createElement("button");
deleteButton.innerText = "Deletar";
deleteButton.name = "delete";
deleteButton.type = "button";
deleteButton.value = id;
imageContainer.appendChild(deleteButton);
preview.appendChild(imageContainer);
}
});
// remove images from preview if not in the Map object
preview.querySelectorAll('.image-container').forEach(div => {
if (!images.has(div.id)) {
div.remove();
}
});
}
function dataURItoBlob(dataURI) {
let byteString = atob(dataURI.split(',')[1]);
let mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0];
let ab = new ArrayBuffer(byteString.length);
let ia = new Uint8Array(ab);
for (var i = 0; i < byteString.length; i++) {
ia[i] = byteString.charCodeAt(i);
}
return new Blob([ab], {
type: mimeString
});
}
<form name="form01" action="" method="post" enctype="multipart/form-data">
<label for="titulo">Título:</label>
<input type="text" id="titulo" name="titulo" required><br><br>
<label for="descricao">Descrição:</label><br>
<textarea id="descricao" name="descricao" required></textarea><br><br>
<div id="preview"></div>
<label>Imagens: <button type="button" name="browse">Browse…</button>
<input type="file" name="images" multiple accept="image/*" style="display:none">
</label>
<small>(Você pode selecionar várias imagens segurando a tecla Ctrl)</small><br><br>
<input type="submit" value="Cadastrar Anúncio">
</form>