原生js选择文件,实现图片预览

490 阅读1分钟

想用于 js 实现一下 选择文件上传

原理 使用 input:type 为 file 选择文件, 遍历所有的 文件列表,生成对应的 li,插入到 一个 ul 里 创建 img 图片 ,使用 URL.createObjectURL api 根据 file 创建对应的 src 并插入到 对应的 li 中,当 img 加载完毕之后 释放 src URL.revokeObjectURL

<input type="file" style="display: none" id="input" />

    <a id="chooseFile">choose File</a>
    
    <div id="fileList">
      <p>No files selected!</p>
  </div>

获取对应的 dom 元素

    
      let fileInput = document.getElementById("input");
      let a = document.getElementById("chooseFile");
      let fileList = document.getElementById("fileList");
a.addEventListener("click", clickHandle);
      function clickHandle(e) {
      // 触发 input 的点击事件
        fileInput.click();
        // 阻止a标签的 默认行为
        e.preventDefault();
      }
      let fs = [];
      fileInput.onchange = function (e) {
        let files = e.target.files;
        fs.push(...files);
        if (fs.length) {
          let ul;
          // 说明已经存在 ul,避免重复创建
          if (
            document.getElementById("$$data") &&
            document.getElementById("$$data").tagName.toLowerCase() == "ul"
          ) {
            ul = document.getElementById("$$data");
          } else {
            ul = document.createElement("ul");
            ul.id = "$$data";
            fileList.innerHTML = "";
            fileList.appendChild(ul);
          }

          // 创建 ul, 遍历创建  li,li 里面创建 img
          // 创建 文档碎片和创建 普通元素不太一样 
          const fragment = document.createDocumentFragment();
          for (let i = 0; i < fs.length; i++) {
          // 清空 ul,否则会重复创建 li
            ul.innerHTML = "";
            const li = document.createElement("li");
            const img = document.createElement("img");
            const button = document.createElement("button");
            // 根据 选择的文件 file 生成 src
            img.src = URL.createObjectURL(fs[i]);
            img.style.height = "60px";
            img.onload = function () {
              // 释放对象 url
              URL.revokeObjectURL(this.src);
            };
            button.innerHTML = "删除";
            button.addEventListener("click", function () {
            // 不能使用 箭头函数
              deleteItem(fs[i], this);
            });
            li.appendChild(img);
            li.appendChild(button);
            fragment.appendChild(li);
          }
          ul.appendChild(fragment);
        }
      };
      function deleteItem(file, e) {
      // 不仅要在 fileList 上删除
        fs = fs.filter((f) => f != file);
        //删除 父节点,注意和 removeChild 的区别
        // https://developer.mozilla.org/zh-CN/docs/Web/API/Node/parentNode
        e.parentNode.remove();
      }

链接总体思路 time 2022.5.21 22:32