文章目录
- drop相关事件说明-MDN
- 演示
- 代码(.html)
演示
代码(.html)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Drag Upload</title>
<style>
html,
body {
height: 100%;
width: 100%;
}
.drag-upload-box {
width: 200px;
height: 130px;
border-radius: 6px;
border: 2px dashed #ccc;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
}
.drag-upload-box.guide {
border-color: orange;
}
.drag-upload-box.available {
border-color: green;
}
.drag-upload-box > * {
pointer-events: none;
}
.drag-upload-box .empty {
color: #ccc;
}
.drag-upload-box .file-name:empty + .empty {
display: unset;
}
.drag-upload-box .file-name + .empty {
display: none;
}
.input-file {
display: none;
}
.obstacle {
width: 100%;
height: 200px;
background: #ccc;
}
</style>
</head>
<body>
<div id="root">
<div id="upload" class="drag-upload-box">
<input id="file" class="input-file" type="file">
<span class="file-name"></span>
<span class="tips empty">点击/拖拽到此处上传文件</span>
</div>
<div class="obstacle no1">
其他元素
</div>
</div>
</body>
<script>
const $ = selector => document.querySelector(selector)
const addEvent = (element, event, handler) => element.addEventListener(event, handler)
const fileInput = $('#file')
const dragBox = $('#upload')
const fileName = dragBox.querySelector('.file-name')
const tips = dragBox.querySelector('.tips')
let inUploadBox = false
let inBody = false
addEvent(dragBox, 'dragenter', handlerEvents)
addEvent(dragBox, 'dragover', handlerEvents)
addEvent(dragBox, 'dragleave', handlerEvents)
addEvent(dragBox, 'drop', handlerEvents)
addEvent(dragBox, 'click', (e) => {
fileInput.click()
})
addEvent(fileInput, 'change', () => {
getFile(fileInput.files[0])
})
const light = {
guide() {
this.classList.add('guide')
this.classList.remove('available')
tips.innerText = '拖拽到此处'
inUploadBox = false
},
available() {
this.classList.add('available')
this.classList.remove('guide')
tips.innerText = '松开鼠标'
inUploadBox = true
},
clearLight() {
this.removeClass('guide', 'available')
tips.innerText = '点击/拖拽到此处上传文件'
inUploadBox = false
},
removeClass() {
this.classList.remove(...arguments)
return this
}
}
Object.assign(dragBox, light)
function handlerEvents(e) {
e.stopPropagation()
e.preventDefault()
switch (e.type) {
case 'dragenter':
dragBox.available()
break
case 'dragleave':
if (inBody) {
dragBox.guide()
} else {
dragBox.clearLight()
}
break
case 'drop':
getFile(e.dataTransfer.files[0])
dragBox.clearLight()
inBody = false
break
default:
break
}
}
function getFile(file) {
console.log(file)
if (!file) {
fileName.innerText = ''
return
}
const fileSize = (file.size / (1024 * 1024)).toFixed(2) + 'MB'
fileName.innerText = file.name + ' ' + fileSize
}
const body = document.body
addEvent(body, 'dragenter', handlerOutEvents)
addEvent(body, 'dragover', handlerOutEvents)
addEvent(body, 'dragleave', handlerOutEvents)
addEvent(body, 'drop', handlerOutEvents)
function handlerOutEvents(e) {
e.stopPropagation()
e.preventDefault()
switch (e.type) {
case 'dragenter':
dragBox.guide()
inBody = true
break
case 'dragover':
break
case 'dragleave':
if (inUploadBox) {
dragBox.removeClass('guide')
}
break
case 'drop':
dragBox.clearLight()
inBody = false
break
default:
break
}
}
</script>
</html>