加了 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 直接无视 - 父级有
pointer-events: none或遮罩层(比如 loading 蒙层),会拦截鼠标事件,导致dragstart完全不执行 - 元素无尺寸(空
<div>且无宽高/内边距/内容),鼠标 hover 都难触发,更别说拖拽
dragover 里不写 preventDefault() 就白搭
drop 事件不会自动触发,它完全依赖 dragover 的持续许可。只在 dragenter 里拦一次、或只在 drop 回调里 preventDefault(),都无效。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
-
dragover事件必须每次触发都执行e.preventDefault() - 目标容器需有明确尺寸或内容,否则
dragover可能无法命中 - 若目标区含子元素,
dragover可能冒泡多次,建议统一绑定到父容器处理
移动端别碰原生 draggable
iOS Safari 和 Android Chrome 对 drag 系列事件支持极差:触摸开始常直接触发长按菜单,dragstart 难捕获,drop 经常静默失败。
立即学习“前端免费学习笔记(深入)”;
- 不是你代码的问题,是平台限制
- 真实项目中必须换方案:用
touchstart/touchmove/touchend模拟拖动逻辑 -
dataTransfer.setDragImage()在移动端基本无效,视觉反馈建议用position: fixed+ 动态更新left/top
最易被忽略的是:跨 iframe 或 Electron webview 场景下,dataTransfer 数据会被清空,类型只剩 ["text/plain"]。这不是 bug,是安全策略强制隔离 —— 需提前把关键数据存进 sessionStorage 或走 IPC 中转。


















