h5 拖拽
HTML5 的拖拽(Drag and Drop, DnD)是一种允许用户通过拖动元素并将其放置在另一个位置的机制。它广泛应用于文件上传、排序、图像拖放等场景。
🌟 一、基础概念#
HTML5 拖拽涉及的主要事件:#
事件名 | 触发时机 |
---|---|
dragstart |
开始拖动元素时 |
drag |
拖动过程中持续触发 |
dragenter |
被拖拽物进入目标元素时 |
dragover |
被拖拽物悬停在目标元素上 |
dragleave |
被拖拽物离开目标元素时 |
drop |
被拖拽物释放到目标元素上 |
dragend |
拖动操作结束时(成功或取消) |
🧱 二、核心 API 解释#
1. event.dataTransfer.dropEffect
#
定义用户释放鼠标后要执行的拖拽操作类型。
可选值包括:
'none'
:不能放置(默认值)'copy'
:复制被拖拽元素'move'
:移动被拖拽元素'link'
:创建链接关系(很少用)
你设置为 'copy'
,意味着目标元素接受被拖拽物的 “复制” 操作,通常用于文件上传、拖入图片等场景。
2. event.dataTransfer.effectAllowed
#
在 dragstart
中设置,表示允许的操作类型:
event.dataTransfer.effectAllowed = 'copyMove';
它可以是以下值之一:
'none'
,'copy'
,'copyLink'
,'copyMove'
,'link'
,'linkMove'
,'move'
,'all'
,'uninitialized'
如果目标 dropEffect
和源 effectAllowed
不匹配,拖拽将失败。
📦 三、拖拽实现步骤#
1. 设置可拖拽元素#
<div id="drag-item" draggable="true">拖我</div>
2. 编写拖拽逻辑#
const dragItem = document.getElementById('drag-item');
const dropZone = document.getElementById('drop-zone');
dragItem.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text/plain', 'Hello, Drop Zone!');
event.dataTransfer.effectAllowed = 'copy';
});
dropZone.addEventListener('dragover', (event) => {
event.preventDefault(); // 必须阻止默认事件,否则 drop 不会触发
event.dataTransfer.dropEffect = 'copy'; // 提示浏览器要使用复制行为
});
dropZone.addEventListener('drop', (event) => {
event.preventDefault();
const data = event.dataTransfer.getData('text/plain');
dropZone.innerText = `接收到:${data}`;
});
3. HTML 示例#
<div id="drag-item" draggable="true" style="width:100px;height:100px;background:red">拖我</div>
<div id="drop-zone" style="width:300px;height:300px;border:2px dashed gray">放到我这</div>
🧠 小提示#
一定要调用
event.preventDefault()
,否则drop
事件不会触发。拖拽文件时可以使用
dataTransfer.files
读取文件列表。可以自定义拖拽图标:
event.dataTransfer.setDragImage()
。
在 HTML5 拖拽(Drag and Drop)中,copy
和 move
是通过 dataTransfer.dropEffect
和 effectAllowed
控制的操作类型,它们的作用是告诉浏览器和用户,拖拽的目标是复制数据,还是移动数据。
🧭 它们的作用可以从两个角度来看:#
✅ 1. 用户交互上的提示#
当你设置 dropEffect = 'copy'
或 'move'
时,操作系统或浏览器会显示不同的光标图标:
dropEffect 值 |
图标含义 | 用户理解为 |
---|---|---|
'copy' |
加号光标(➕) | 复制一个副本 |
'move' |
箭头或小手光标 | 移动原始元素 |
这有助于用户明确:拖的是副本?还是原始对象?
⚙️ 2. 程序行为控制#
你可以根据拖拽意图决定是 “复制” 一份新内容,还是 “移动” 已有内容:
📄 copy
#
拖拽的是一个副本
原始元素不发生变化
常见于:
拖拽文件上传(文件不会从本地删除)
拖入图片到编辑器中
✂️ move
#
拖拽的是原始对象本身
源元素可能被删除或移动
常见于:
拖动列表项重新排序
拖拽文件在文件夹之间移动
🧪 示例区别#
// copy
event.dataTransfer.effectAllowed = 'copy';
event.dataTransfer.dropEffect = 'copy';
// move
event.dataTransfer.effectAllowed = 'move';
event.dataTransfer.dropEffect = 'move';
在 drop 事件中你可以根据需要 “处理”:
dropZone.addEventListener('drop', (event) => {
const data = event.dataTransfer.getData('text/plain');
if (event.dataTransfer.dropEffect === 'copy') {
// 创建一个副本
const copy = document.createElement('div');
copy.textContent = data;
dropZone.appendChild(copy);
} else if (event.dataTransfer.dropEffect === 'move') {
// 移动元素(通常需要从原位置删除)
dropZone.textContent = `移动了:${data}`;
}
});
📝 总结#
类型 | 含义 | 场景 |
---|---|---|
copy | 保留原对象,复制 | 拖入编辑器 / 上传文件等 |
move | 移除原对象,移动 | 拖拽排序、拖动文件到新位置 |
本作品采用《CC 协议》,转载必须注明作者和本文链接