继上篇 原生实现文件上传界面交互
Input原生支持拖拽,可以直接将文件拖到input框内实现拖拽效果,但是有时候可能存在兼容性等问题,在这里通过给div添加拖拽事件实现文件拖拽上传效果
给div添加拖拽事件
// 原生实现上传函数
function upload(file, onProgress, onFinish) {
const xhr = new XMLHttpRequest()
// 上传完成
xhr.onload = function () {
const res = JSON.parse(xhr.responseText)
onFinish(res)
}
// 上传进度
xhr.upload.onprogress = (e) => {
const percent = Math.floor((e.loaded / e.total) * 100)
onProgress(percent)
}
xhr.open('POST', 'http://xxxxxxxxx')
const form = new FormData()
form.append('avatar', file)
xhr.send(form)
// 取消网络请求
return function () {
xhr.abort()
}
}
// 拖拽进入事件
doms.select.ondragenter = (e) => {
// 阻止浏览器默认行为
e.preventDefault()
}
// 拖拽离开
doms.select.ondragleave = (e) => {}
// 拖拽中
doms.select.ondragover = (e) => {
// 阻止浏览器默认行为
e.preventDefault()
}
// 拖到div放手后触发
doms.select.ondrop = (e) => {
// 阻止浏览器默认行为
e.preventDefault()
// 判断被拖动类型
if (!e.dataTransfer.types.includes('Files')) {
alert('仅支持拖拽文件')
return
}
// 判断拖拽文件数量
const files = e.dataTransfer.files
if (files.length !== 1) {
alert('仅支持单文件上传')
return
}
// 直接赋值不能出发input的onchange事件
doms.selectFile.files = files
changeHandler()
}
// 拿到文件并上传
function changeHandler() {
if (doms.selectFile.files.length === 0) {
return
}
const file = doms.selectFile.files[0]
if (!validateFile(file)) {
return
}
// 切换界面
showArea('progress')
// 显示预览图
const reader = new FileReader()
reader.onload = (e) => {
doms.img.src = e.target.result
}
reader.readAsDataURL(file)
// 上传
cancelUpload = upload(
file,
function (val) {
// 进度变换了
setProgress(val)
},
function (resp) {
showArea('result')
}
)
}
// 拿到选择的文件
doms.selectFile.onchange = changeHandler