想用于 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