一、核心概念

1. 拖放三要素

  • 拖动的元素:被拖拽的物品
  • 待传输的数据:通过 DataTransfer 传递
  • 放置目标:可放置的区域

2. 重要特性

  • 拖拽过程中,原始元素保持原位不动
  • 浏览器创建半透明幽灵图像跟随鼠标
  • 所有业务逻辑都需要手动实现

二、事件系统

事件流程

1
dragstart → drag → dragenter → dragover → dragleave → drop → dragend

事件详解

事件 触发元素 作用
dragstart 可拖动元素 设置拖拽数据和权限
drag 可拖动元素 拖拽过程中连续触发
dragenter 目标元素 第一次进入目标边界
dragover 目标元素 在目标边界内移动
dragleave 目标元素 离开目标边界
drop 目标元素 在目标上释放
dragend 可拖动元素 拖拽操作结束

三、DataTransfer 对象

1. 数据操作

1
2
3
4
5
6
7
8
9
// 设置数据
event.dataTransfer.setData("text/plain", "数据内容");
event.dataTransfer.setData("application/json", JSON.stringify(data));

// 获取数据
const data = event.dataTransfer.getData("text/plain");

// 清除数据
event.dataTransfer.clearData();

2. 视觉控制

1
2
3
4
5
6
7
8
// 自定义拖拽图像
event.dataTransfer.setDragImage(element, offsetX, offsetY);

// 控制操作权限
event.dataTransfer.effectAllowed = "copyMove"; // copy, move, link, copyMove, all, none

// 设置意图操作
event.dataTransfer.dropEffect = "copy"; // copy, move, link, none

3. 文件处理

1
2
3
4
const files = event.dataTransfer.files;
for (let file of files) {
console.log(file.name, file.size, file.type);
}

四、关键要点

1. 必须的操作

1
2
3
4
// dragover 中必须阻止默认行为
dropZone.addEventListener("dragover", (event) => {
event.preventDefault(); // 否则 drop 不会触发
});

原因:浏览器的默认行为是将大多数元素视为”不可放置”目标。阻止默认行为就是告诉浏览器:”这个元素可以接受放置”。

2. DataTransfer 访问权限

事件 读取数据 写入数据 设置 dropEffect
dragstart
dragover
drop
dragend

3. effectAllowed 与 dropEffect 匹配

源权限 目标意图 结果
copy copy ✅ 允许复制
copy move ❌ 禁止操作
copyMove copy ✅ 允许复制
copyMove move ✅ 允许移动