首页 / HTML5 入门教程 / 拖放 API

HTML5 入门教程

拖放 API

本教程共 110 篇 · 第 92 篇 · 更新于 2026-07-28 · 约 4 分钟阅读

HTML5HTML5 入门教程拖放Drag Drop交互事件

92. 拖放 API

本节目标:学会使用 HTML5 拖放 API,理解拖拽事件序列,能实现最基本的拖拽移动和拖拽放置效果。

什么是拖放

拖放就是鼠标按住一个元素,移动到另一个位置松开。HTML5 把它变成了原生能力,不需要额外库。

任何元素都能拖,只要加一个属性:

<div draggable="true">我能被拖动</div>

拖拽事件序列

拖拽分两个角色:被拖的源接住的目标

源的事件

事件触发时机
dragstart开始拖动时
drag拖动过程中持续触发
dragend拖动结束时

目标的事件

事件触发时机
dragenter拖入目标区域
dragover在目标区域内悬停
dragleave拖出目标区域
drop松开鼠标,放置

最小可运行示例

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <style>
    #dropZone {
      width: 300px; height: 200px;
      border: 2px dashed #ccc;
      text-align: center; line-height: 200px;
    }
    #dropZone.dragover {
      background: #e0f7fa;
      border-color: #00bcd4;
    }
  </style>
</head>
<body>
  <div id="dragItem" draggable="true">拖动我</div>
  <div id="dropZone">放到这里</div>

  <script>
    const item = document.getElementById("dragItem");
    const zone = document.getElementById("dropZone");

    // 开始拖动:存数据
    item.addEventListener("dragstart", function (e) {
      e.dataTransfer.setData("text/plain", "被拖动的数据");
      this.style.opacity = "0.5";
    });

    // 拖动结束:恢复样式
    item.addEventListener("dragend", function () {
      this.style.opacity = "1";
    });

    // 必须阻止 dragover 的默认行为,否则 drop 不触发
    zone.addEventListener("dragover", function (e) {
      e.preventDefault();
      this.classList.add("dragover");
    });

    // 拖出时去掉高亮
    zone.addEventListener("dragleave", function () {
      this.classList.remove("dragover");
    });

    // 放置时获取数据
    zone.addEventListener("drop", function (e) {
      e.preventDefault();
      this.classList.remove("dragover");
      const data = e.dataTransfer.getData("text/plain");
      this.innerHTML = "收到:" + data;
    });
  </script>
</body>
</html>

关键点:e.preventDefault()

这个坑一定记住:必须调用 dragover 事件的 preventDefault(),否则 drop 事件不会触发。

这是因为浏览器默认不允许放置元素。你不明确说”欢迎放我就这里”,它就拒绝。

拖拽传数据

DataTransfer 对象在源和目标之间传数据:

// 源:存数据
e.dataTransfer.setData("text/plain", "hello");
e.dataTransfer.setData("text/html", "<b>hello</b>");

// 取数据
const text = e.dataTransfer.getData("text/plain");

键名常用 text/plaintext/htmlURL 等 MIME 类型。

Tip

实际开发中,经常用 setData 存元素的 id,drop 时根据 id 移动 DOM。

实际应用:图片预览拖拽

用户把图片文件拖进来,直接显示预览:

zone.addEventListener("drop", function (e) {
  e.preventDefault();
  const files = e.dataTransfer.files; // 获取文件列表
  if (files.length > 0) {
    const file = files[0];
    if (file.type.startsWith("image/")) {
      const url = URL.createObjectURL(file);
      zone.innerHTML = `<img src="${url}" width="200">`;
    }
  }
});
Note

拖放 API 在移动端支持有限。移动端通常需要 Touch Events 或第三方库。如果是 PC 端的后台管理系统、看板等工具,拖放 API 够用。

浏览器兼容性

拖放 API 在现代浏览器中都支持。dataTransfer.files 在主流浏览器也没问题。注意某些老版本 Firefox 对 SVG 拖拽支持不太好。