Appearance
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.upload-container {
width: 500px;
height: 100%;
border: 1px solid #ebebeb;
margin: 0 auto;
margin-top: 50px;
box-shadow: 3px 3px rgba(0, 0, 0, .3);
padding: 0 30px;
padding-bottom: 50px;
}
.upload-container .upload-btn {
margin-top: 10px;
}
.upload-container .upload-btn .disabled {
background-color: #dddddd !important;
}
.upload-container .upload-btn .select, .submit{
height: 32px;
background-color: #409eff;
font-size: 12px;
border: none;
border-radius: 3px;
color: #fff;
}
.upload-container .upload-btn .submit {
margin-left: 10px;
}
.upload-container .upload-tip {
font-size: 12px;
color: #606266;
margin-top: 10px;
}
.upload-container .upload-list {
width: 360px;
}
.upload-container .upload-list .list {
height: 26px;
color: #606266;
font-size: 14px;
margin-top: 10px;
display: flex;
justify-content: space-between;
align-items: center;
}
.upload-container .upload-list .list .left .file {
width: 14px;
height: 14px;
}
.upload-container .upload-list .list .right .delete {
width: 14px;
height: 14px;
}
</style>
</head>
<body>
<section class="upload-container">
<input
name="upload-inp"
type="file"
multiple
style="display: none;"
>
<div class="upload-btn">
<button class="select">点击上传</button>
<button class="submit">上传服务器</button>
</div>
<div class="upload-tip">
只能上传JPG/PNG/JPEG/WEBP文件, 且大小不能超过500kb
</div>
<div class="upload-list">
<!-- <div class="list">
<div class="left">
<img class="file" src="./static/imgs/file.png" alt="">
<span>foo.jepg</span>
</div>
<div class="right">
<img class="delete" src="./static/imgs/delete.png" alt="">
</div>
</div> -->
</div>
</section>
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.21.1/axios.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/qs/6.10.1/qs.js"></script>
<script src="./request.js"></script>
<script>
let uploadContainer = document.querySelector('.upload-container'),
uploadInp = uploadContainer.querySelector('[name=upload-inp]'),
uploadBtn = uploadContainer.querySelector('.upload-btn'),
uploadList = uploadContainer.querySelector('.upload-list'),
select = uploadBtn.querySelector('.select'),
submit = uploadBtn.querySelector('.submit'),
_files = []
// 点击上传文件按钮, 触发input的点击事件
select.addEventListener('click', function () {
if (isDisabled()) {
// 按钮禁用
return
}
uploadInp.click()
})
// 清除list
function clearList (index) {
if (typeof index === 'number') {
// 删除指定
_files = _files.filter((_, idx) => idx !== index)
uploadList.removeChild(uploadList.children[index])
} else {
// 全部删除
_files = []
uploadList.innerHTML = ''
}
}
// 禁用按钮
function isDisabled () {
return select.classList.contains('disabled') || submit.classList.contains('disabled')
}
// 选择图片时的处理
uploadInp.addEventListener('change', function () {
let isPass = true,
tempFiles = [] // 本次选择中能够通过的图片
Array.prototype.forEach.call(this.files, file => {
if (!/(jpg|png|jepg|webp)/i.test(file.type)) {
// 限制图片类型
isPass = false
} else if (file.size > 500 * 1024) {
// 再限制文件大小
isPass = false
}
if (isPass) {
tempFiles.push(file)
}
})
// 通过的图片添加到列表中
tempFiles.forEach(file => {
uploadList.innerHTML += `
<div class="list">
<div class="left">
<img class="file" src="./static/imgs/file.png" alt="">
<span>${file.name}</span>
</div>
<div class="right">
<img class="delete" src="./static/imgs/delete.png" alt="">
</div>
</div>
`
})
// 如果下次选择相同图片, 也让上传
uploadInp.value = ''
// 更新图片集合
_files = _files.concat(tempFiles)
})
// 删除指定list
uploadList.addEventListener('click', function (event) {
if (!isDisabled() && event.target.className === 'delete') {
// 获取下标
let children = uploadList.children, // 所有list
target = event.target.parentNode.parentNode, // 当前点击list
index = Array.prototype.indexOf.call(children, target)
clearList(index)
}
})
// 上传图片
submit.addEventListener('click', function () {
if (isDisabled()) {
// 按钮禁用
return
}
if (_files.length === 0) {
alert('你还没有选择图片~')
return
}
// 上传过程中禁用按钮
select.classList.toggle('disabled')
submit.classList.toggle('disabled')
// 上传图片 多张图片上传本质就是循环进行单张图片上传
let result = _files.map((file, index) => {
let formData = new FormData,
list = uploadList.children[index], // list中的index和_files中的index是对应的
right = list.querySelector('.right')
formData.append('file', file)
formData.append('filename', file.name)
return instance.post('/upload-single', formData, {
onUploadProgress (event) {
// 设置进度
right.innerHTML = ''
right.innerText = (event.loaded / event.total * 100).toFixed(2) + '%'
}
})
.then(response => {
if (response.status === 0) {
right.innerText = '100.00%'
return Promise.resolve(response.statusText)
} else {
return Promise.reject(response.statusText)
}
})
.catch(reason => {
return Promise.reject(reason)
})
})
Promise.all(result)
.then(val => {
alert('文件上传成功')
})
.catch(reason => {
console.log(reason)
alert('文件上传失败')
})
.finally(() => {
_files = []
clearList()
// 取消禁用
select.classList.toggle('disabled')
submit.classList.toggle('disabled')
})
})
</script>
</body>
</html>