加了 draggable="true" 仍拖不动,因浏览器仅对图片、链接、选中文本开放原生拖放;需监听 dragstart 并调用 setdata,且 dragover 必须每次 preventdefault(),移动端应避免使用原生 drag 事件。

draggable="true" 只是拖拽的起点,不是完整功能。不配事件、不设数据、不拦默认行为,元素就“拖不动”或“放不下”。
为什么加了 draggable="true 还是拖不动
浏览器默认只对图片、链接、选中文本开放原生拖放权限;其他元素即使写了 draggable="true",也仅改变光标样式,dragstart 事件根本不会触发。
- 必须显式监听
dragstart,并在其中调用e.dataTransfer.setData('text/plain', '...')—— 即使传空字符串也不可省略 -
draggable="auto"不可靠:Chrome/Safari 对<div> 忽略它,Firefox 直接无视 <li>父级有 <code>pointer-events: none或遮罩层(比如 loading 蒙层),会拦截鼠标事件,导致dragstart完全不执行 - 元素无尺寸(空
<div> 且无宽高/内边距/内容),鼠标 hover 都难触发,更别说拖拽 <h3> <code>dragover里不写preventDefault()就白搭drop事件不会自动触发,它完全依赖dragover的持续许可。只在dragenter里拦一次、或只在drop回调里preventDefault(),都无效。-
dragover事件必须每次触发都执行e.preventDefault() - 目标容器需有明确尺寸或内容,否则
dragover可能无法命中 - 若目标区含子元素,
dragover可能冒泡多次,建议统一绑定到父容器处理
移动端别碰原生
draggableiOS Safari 和 Android Chrome 对
drag系列事件支持极差:触摸开始常直接触发长按菜单,dragstart难捕获,drop经常静默失败。- 不是你代码的问题,是平台限制
- 真实项目中必须换方案:用
touchstart/touchmove/touchend模拟拖动逻辑 -
dataTransfer.setDragImage()在移动端基本无效,视觉反馈建议用position: fixed+ 动态更新left/top
最易被忽略的是:跨 iframe 或 Electron webview 场景下,
dataTransfer数据会被清空,类型只剩["text/plain"]。这不是 bug,是安全策略强制隔离 —— 需提前把关键数据存进sessionStorage或走 IPC 中转。 -











