Drag API 拖拽事件
HTML5 Drag API 的 7 个拖拽事件及使用方法
问题
HTML5 Drag API 有哪些拖拽相关的事件?它们分别在什么时候触发?
解答
Drag API 共有 7 个事件,分为两类:拖拽元素事件和目标区域事件。
事件分类
| 事件 | 触发对象 | 触发时机 |
|---|---|---|
dragstart | 被拖拽元素 | 开始拖拽时 |
drag | 被拖拽元素 | 拖拽过程中持续触发 |
dragend | 被拖拽元素 | 拖拽结束时 |
dragenter | 目标元素 | 拖拽元素进入目标区域时 |
dragover | 目标元素 | 拖拽元素在目标区域上方时持续触发 |
dragleave | 目标元素 | 拖拽元素离开目标区域时 |
drop | 目标元素 | 在目标区域释放时 |
完整示例
<!DOCTYPE html>
<html>
<head>
<style>
.draggable {
width: 100px;
height: 100px;
background: #3498db;
color: white;
display: flex;
align-items: center;
justify-content: center;
cursor: move;
}
.dropzone {
width: 300px;
height: 200px;
border: 2px dashed #ccc;
margin-top: 20px;
display: flex;
align-items: center;
justify-content: center;
}
.dropzone.over {
border-color: #3498db;
background: #ecf0f1;
}
</style>
</head>
<body>
<div class="draggable" draggable="true" id="box">拖拽我</div>
<div class="dropzone" id="zone">放置区域</div>
<script>
const draggable = document.getElementById('box');
const dropzone = document.getElementById('zone');
// ========== 拖拽元素事件 ==========
// 开始拖拽
draggable.addEventListener('dragstart', (e) => {
// 设置拖拽数据
e.dataTransfer.setData('text/plain', e.target.id);
// 设置拖拽效果
e.dataTransfer.effectAllowed = 'move';
console.log('dragstart: 开始拖拽');
});
// 拖拽过程中持续触发
draggable.addEventListener('drag', (e) => {
// 注意:这个事件触发频率很高,避免执行耗时操作
console.log('drag: 拖拽中...');
});
// 拖拽结束
draggable.addEventListener('dragend', (e) => {
console.log('dragend: 拖拽结束');
});
// ========== 目标区域事件 ==========
// 进入目标区域
dropzone.addEventListener('dragenter', (e) => {
e.preventDefault();
dropzone.classList.add('over');
console.log('dragenter: 进入目标区域');
});
// 在目标区域上方(必须阻止默认行为才能触发 drop)
dropzone.addEventListener('dragover', (e) => {
e.preventDefault(); // 关键:允许放置
e.dataTransfer.dropEffect = 'move';
console.log('dragover: 在目标区域上方');
});
// 离开目标区域
dropzone.addEventListener('dragleave', (e) => {
dropzone.classList.remove('over');
console.log('dragleave: 离开目标区域');
});
// 放置
dropzone.addEventListener('drop', (e) => {
e.preventDefault();
dropzone.classList.remove('over');
// 获取拖拽数据
const id = e.dataTransfer.getData('text/plain');
const element = document.getElementById(id);
// 将元素移动到目标区域
dropzone.appendChild(element);
console.log('drop: 放置完成');
});
</script>
</body>
</html>
dataTransfer 对象
dataTransfer 用于在拖拽过程中传递数据:
// 设置数据
e.dataTransfer.setData('text/plain', 'hello');
e.dataTransfer.setData('application/json', JSON.stringify({ id: 1 }));
// 获取数据(只能在 drop 事件中获取)
const text = e.dataTransfer.getData('text/plain');
// 设置拖拽效果
e.dataTransfer.effectAllowed = 'copy'; // copy, move, link, all
e.dataTransfer.dropEffect = 'copy';
// 设置拖拽图像
e.dataTransfer.setDragImage(img, offsetX, offsetY);
关键点
- 元素需设置
draggable="true"才能拖拽 - 必须在
dragover中调用e.preventDefault()才能触发drop事件 dataTransfer.getData()只能在drop事件中调用drag和dragover事件触发频率高,避免执行耗时操作- 事件触发顺序:
dragstart→drag→dragenter→dragover→dragleave/drop→dragend
目录