无法使用 JavaScript 从输入中删除图像

问题描述 投票:0回答:1

我在 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 = "";
});

但这不起作用,因为当您插入这行代码时,所有图像都会被删除,而不是唯一选择的图像。

如何解决?

javascript html forms dom
1个回答
0
投票

这是一个很长的示例,但我的想法是维护所选文件的数组(此处为 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>

© www.soinside.com 2019 - 2024. All rights reserved.