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.

获得所需结果的方法

您可以更改代码以获得所需的外观和功能。

总结以下代码的作用:

  1. 创建一个新的 FormData 实例
  2. 接受来自文件输入的文件
  3. 将文件附加到在步骤 1 中创建的 FormData 的名为 file-${index} 的字段中
  4. 为每个 File
  5. 创建一个 FileReader 实例
  6. FileReader 读取文件内容,returns data: URL 将文件数据表示为 base64 编码字符串。
  7. 创建一个 span 元素并向其附加一个 img 元素,其中第 5 步的文件内容为 src
  8. click 侦听器附加到 span,因此当用户单击图像时,相应的文件将从步骤 1 的 FormData 中删除,span 将从 DOM
  9. 中删除
  10. 当用户使用 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>

How to upload a file using Fetch的例子供参考。