draggable="true"仅启用拖拽能力,不自动传递数据;必须在dragstart中调用setdata("text/plain", data)传字符串,drop中用相同type调getdata()读取,且dragover需preventdefault()才能触发drop。

draggable="true"只是开关,不自动传参
设了 draggable="true" 后元素能拖、光标变手型,但 dataTransfer 里是空的——它不会自动把 ID、class 或自定义属性塞进去。想让目标区知道“拖的是谁”,必须手动调 e.dataTransfer.setData()。
dragstart 中必须调 setData(),且只认字符串
setData() 只能在 dragstart 事件里调用,其他地方调无效;而且第二个参数只能是字符串,不能传对象、DOM 节点或函数。
- 推荐格式用
"text/plain":兼容性最好,IE、Chrome、Firefox、Safari 都支持 - 避免用
"Text"(IE 风格写法),现代浏览器虽能 fallback,但行为不一致 - 值可以是
e.target.id、e.target.dataset.itemId,或序列化后的 JSON:JSON.stringify({type: 'card', id: 123}) - 别在
drag或dragend里试图补 setData() —— 浏览器会忽略
drop 里用 getData() 读取,但得匹配 format
getData() 必须和 setData() 时用的 format 完全一致,否则返回空字符串。常见错误是写成 e.dataTransfer.getData('Text') 却用了 setData('text/plain', ...)。
- 读取前建议先检查是否为空:
const id = e.dataTransfer.getData('text/plain') || ''; - 如果存的是 JSON 字符串,记得
JSON.parse(),但要包 try-catch -
dragover里不能读getData()—— 浏览器禁止,防止信息泄露
移动端和表单控件是硬伤,别硬刚
iOS Safari 对原生 draggable 支持极差,拖动卡顿、drop 不触发是常态;<input>、<textarea></textarea> 这类元素即使加了 draggable="true",浏览器也直接无视。
- 真要拖表单内容,得用
mousedown → mousemove → mouseup自实现,绕过原生 API - 移动端优先考虑 touch 事件 + CSS transform 模拟拖拽,而不是依赖
dragstart/drop - 若必须用原生拖拽,至少在
dragstart里加e.dataTransfer.effectAllowed = 'move',部分安卓浏览器能稍稳一点
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











