- 当 drag元素被拖动时,原来容器中的drag元素并不会消失
- 需要手动隐藏
- 添加 class=’visible’
- 如果同步操作会立马触发 dragend事件导致拖动效果消失,
- 所以在 setTimeout的回调中,异步设置可确保拖动操作开始后,再隐藏 drag元素
- 在 dragEnter和 dragOver方法中,要通过 e.preventDefault来取消事件
- 表示容器是一个合法的 droppable元素,接收拖拽的容器,否则:
- 接收容器的drop事件将无法触发,接下来的操作也将无法进行
- 在 dragDrop方法中,直接使用append方法将draggable元素移动至当前容器下
drag事件触发顺序
dragover会一直触发
.visible 为drag拖拽开始后,隐藏拖拽的元素
.dragging为drag拖拽元素正在被拖动的状态,增加黄色border
.drag-over为draggable元素被拖动到容器上方时容器的状态,增加灰色虚线border
<!DOCTYPE html>
<html lang="zh-CN">
<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>html5-drag drop</title>
<style>
body {
background-color: rgba(233, 150, 122, 0.1);
}
/* 拖拽的元素 */
.draggable {
background-image: url('http://via.placeholder.com/150x150');
position: relative;
height: 150px;
width: 150px;
top: 5px;
left: 5px;
cursor: move;
}
/* 接收容器的样式 */
.droppable {
display: inline-block;
height: 160px;
width: 160px;
margin: 10px;
border: 3px salmon solid;
background-color: white;
}
/* 拖拽时的样式 */
.dragging {
border: 4px yellow solid;
cursor: move;
}
/* dragOver 拖拽接收的容器样式 */
.drag-over {
background-color: #f4f4f4;
border-style: dashed;
}
/* dragStart隐藏拖拽的元素 */
.visible {
display: none;
}
</style>
</head>
<body>
<div class="droppable">
<div class="draggable" draggable="true"></div>
</div>
<div class="droppable"></div>
<div class="droppable"></div>
<div class="droppable"></div>
<div class="droppable"></div>
<script>
let timer;
// 查询draggable和droppable
const draggable = document.querySelector('.draggable');
const droppables = document.querySelectorAll('.droppable'); // 接收的容器
// 监听 drag的相关事件
draggable.addEventListener('dragstart', dragStart);
draggable.addEventListener('dragend', dragEnd);
function dragStart(e) {
// 当前拖拽的元素添加拖拽样式
this.className += ' dragging';
timer = setTimeout(() => {
this.className += ' visible';
}, 0);
}
function dragEnd() {
this.className = 'draggable';
clearTimeout(timer);
console.log(timer)
}
// 监听 drop的相关事件
for (const droppable of droppables) {
droppable.addEventListener('dragover', dragOver); //
droppable.addEventListener('dragleave', dragLeave); // 拖拽元素离开容器
droppable.addEventListener('dragenter', dragEnter); // 拖拽元素进入容器范围
droppable.addEventListener('drop', dragDrop); // 释放拖拽
}
// 高频事件,慎用
function dragOver(e) {
e.preventDefault();
console.log('over')
}
// 拖拽进入
function dragEnter(e) {
e.preventDefault();
console.log('enter')
this.className += ' drag-over';
}
// 拖拽离开
function dragLeave(e) {
console.log('leave')
this.className = 'droppable';
}
// 拖拽释放
function dragDrop(e) {
this.className = 'droppable';
this.append(draggable);
console.log('drop')
}
</script>
</body>
</html>