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 .active {
color: #409eff;
}
.upload-container .upload-list .list .left .file {
width: 14px;
height: 14px;
}
.upload-container .upload-list .list .right .delete, .complete {
width: 14px;
height: 14px;
}
.upload-container .upload-progress {
display: none;
margin-top: 20px;
width: 300px;
height: 6px;
border-radius: 100px;
background-color: #ddd;
}
.upload-container .upload-progress .progress {
border-radius: 100px;
height: 100%;
width: 0%;
background-color: #67c23a;
transition: width .3s;
}
</style>
</head>
<body>
<section class="upload-container">
<input name="upload-inp" type="file" style="display: none;">
<!-- <input name="upload-inp" type="file" accept=".png,.jpg,.jpeg,.webp" style="display: none;"> -->
<div class="upload-btn">
<button class="select" type="button">点击上传</button>
</div>
<div class="upload-tip">
只能上传JPG/PNG/JPEG/WEBP文件, 且大小不能超过500kb
</div>
<div class="upload-list"></div>
<div class="upload-progress">
<div class="progress"></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="https://cdn.bootcdn.net/ajax/libs/spark-md5/3.0.0/spark-md5.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'),
uploadProgress = uploadContainer.querySelector('.upload-progress'),
progress = uploadProgress.querySelector('.progress'),
select = uploadBtn.querySelector('.select'),
_file = null
// 点击上传文件按钮, 触发input的点击事件
select.addEventListener('click', function () {
if (isDisabled()) {
// 按钮禁用
return
}
if (_file) {
alert('一次只能上传一张图片~')
return
}
uploadInp.click()
})
// 禁用按钮
function isDisabled () {
return select.classList.contains('disabled')
}
// 图片转化为Buffer
function img2Buffer (file) {
return new Promise((resolve, reject) => {
let fileReader = new FileReader
fileReader.readAsArrayBuffer(file)
fileReader.onload = function (event) {
resolve(event.target.result)
}
})
}
// 根据内容生成hash名
function hashHandler (buffer) {
let spark = new sparkMD5.ArrayBuffer(),
hash = null,
suffix = /\.([0-9a-zA-Z]+)$/.exec(_file.filename)
spark.append(buffer)
hash = spark.end()
return {
buffer,
hash,
suffix,
filename: hash + suffix
}
}
// 文件切片
function fileSlice (buffer) {
let formData = new FormData
// formData沿着原型链能找到slice方法, 被用于文件切片(单位B),
// 文件切片需要关注切片数量和切片大小
// 先按照固定切片大小计算出需要的切片数量
// 如果切片数量不大于限制值, 使用该方案
// 如果切片数量大于限制值, 设置切片数量为限制值, 增大每个切片的大小
let fileSize = _file.size // 文件大小
limit = 100, // 最多分100个切片
sliceSize = 1 * 1024, // 每个切片默认1kb
sliceCount = Math.ceil(fileSize / sliceSize) // 所需切片数量
if (sliceCount > limit) {
// 超出切片数量限制
sliceSize = fileSize / limit
sliceCount = limit
}
// formData.slice(0, 1024) // 切[0, 1023)
sliceSize
}
// 选择图片时的处理
uploadInp.addEventListener('change', function () {
_file = this.files[0]
if (!_file) {
return
}
if (isDisabled()) {
// 按钮禁用
return
}
if (!_file) {
alert('你还没有选择图片~')
return
}
// 上传过程中禁用按钮
select.classList.toggle('disabled')
// 显示进度条
uploadProgress.style.display = 'block'
console.log(_file)
})
</script>
</body>
</html>