正在加载...

HTML 拖放

上一课 Geolocation 在授权后请求坐标。本课离开坐标,介绍 HTML 拖放:标记可拖内容、用 dataTransfer 携带小载荷,并决定放下时做什么。范围务实——draggable、dragover 上的 preventDefault、移动或贴标签——不是 sortable 库或上传应用课。

为何在 HTML 课学拖放

初学者常想把卡片拖进盒子。原生 DnD 是常见的第一套 API。在 Geolocation 之后,分工不同:HTML 标记源;JS 拥有事件与 drop 含义。

直接回答

1) draggable="true"。2) 在 dragstart 中 setData。3) 在 dragover 上 preventDefault。4) 在 drop 中 getData 并改 DOM/UI。5) 没有特殊 dropzone 标签。6) 若重要,提供按钮/键盘路径。

📊 dragstart vs dragover vs drop

Topic dragstart dragover drop
Typical role Start drag; set dataTransfer Allow drop (preventDefault) Apply the result
Runs on Draggable source Potential target (often) Drop target
Must preventDefault? Usually no Yes — so drop can fire Yes — avoid default navigation quirks
Beginner payload setData("text/plain", id) — getData + move/label
This course depth Required Required Required (simple move/label)

微型移入区域演示

蓝色框可拖;放下后进入虚线区。若 dragover 不 preventDefault,drop 常不触发。

Move a node into a drop zone

html
<div id="item" draggable="true" style="padding:8px;background:#cdf;width:120px;">Drag me</div>
<div id="zone" style="margin-top:12px;padding:24px;border:2px dashed #666;">Drop here</div>
<script>
const item = document.getElementById("item");
const zone = document.getElementById("zone");
item.addEventListener("dragstart", function (e) {
e.dataTransfer.setData("text/plain", "item");
});
zone.addEventListener("dragover", function (e) {
e.preventDefault();
});
zone.addEventListener("drop", function (e) {
e.preventDefault();
zone.appendChild(item);
});
</script>

阅读移动调用

  • draggable 启动手势
  • dragstart 设置 dataTransfer
  • dragover + preventDefault 允许放下
  • drop 改变 DOM
  • 与 Geolocation 不同:无设备坐标
  • 保持演示精简

dataTransfer 载荷演示

有时不移动同一节点——携带文本并在放下时显示,多个源共享一个目标时很有用。

Drop shows dataTransfer text

html
<p id="a" draggable="true" style="display:inline-block;padding:6px;background:#fec;margin-right:8px;">Alpha</p>
<p id="b" draggable="true" style="display:inline-block;padding:6px;background:#cfe;margin-right:8px;">Beta</p>
<div id="tray" style="margin-top:12px;padding:16px;border:2px dashed #444;">Drop a label here</div>
<pre id="note"></pre>
<script>
const tray = document.getElementById("tray");
const note = document.getElementById("note");
function arm(id, label) {
document.getElementById(id).addEventListener("dragstart", function (e) {
e.dataTransfer.setData("text/plain", label);
});
}
arm("a", "Alpha");
arm("b", "Beta");
tray.addEventListener("dragover", function (e) {
e.preventDefault();
});
tray.addEventListener("drop", function (e) {
e.preventDefault();
note.textContent = "Dropped: " + e.dataTransfer.getData("text/plain");
});
</script>

阅读 dataTransfer 思路

  • setData/getData 传递短字符串
  • text/plain 适合初学者
  • 多源一目标
  • 不是上传产品
  • 不是 Geolocation
  • 下一课:web workers

何时使用 DnD

  • 卡片拖入明确区域:适合入门
  • 无替代的关键操作:不好
  • 保存主题:Web Storage
  • GPS:是 Geolocation
  • 完整看板产品:超出本入门

练习 — 拖、放、贴标签

  1. 试移动演示。
  2. 暂时去掉 preventDefault 观察 drop 失败。
  3. 试 dataTransfer 演示。
  4. (可选)无拖动的按钮。
  5. 一句话:Geolocation 读坐标;DnD 用指针移动/贴标签。
  6. 优先真实浏览器窗口。
  7. 预告:web workers。

易错点

  • 忘记 dragover 上的 preventDefault
  • 仅 DnD 界面无替代
  • 期待 dropzone 标签
  • 与 Geolocation 混淆
  • 滥用 DnD 而非按钮
  • 把入门当成完整 sortable 课

小结

  • DnD 使用 draggable、dataTransfer 与三个事件
  • dragover 上的 preventDefault 常必需
  • HTML 标记源;脚本定义 drop
  • 需要时提供非拖动路径
  • Geolocation 是获准坐标;本课是指针移动/贴标签
  • 下一课:web workers

🧠 测试您的知识

准备开始

测试您的知识

通过这个互动测验挑战自己,看看你对这个主题的理解程度如何

❓
5
问题
🎯
70%
及格要求
♾️
∞
时间
🔄
∞
尝试次数

📝 说明

  • 仔细阅读每个问题
  • 为每个问题选择最佳答案
  • 您可以随时重新参加测验
  • 您的进度将显示在顶部