HTML5拖拽需同时设置draggable=”true”和dragstart中调用dataTransfer.setData();drop事件触发前必须在dragover中preventDefault();数据类型须严格匹配;需监听dragend、dragleave清理状态。
HTML5 原生拖拽 API 并不难用,但默认行为多、事件链琐碎、浏览器兼容细节多,直接写容易卡在 dragstart 后没反应,或拖着拖着就跳转页面——根本不是“没生效”,而是你没阻止默认行为。
为什么拖不了?draggable 属性和 dragstart 事件缺一不可
仅给元素加 draggable="true" 不够,浏览器不会自动让它可拖;必须监听 dragstart 并至少设置一次 dataTransfer,否则拖拽会静默失败(尤其 Chrome/Firefox)。
-
draggable="true"是前提,但只控制“是否允许拖”,不触发任何逻辑 - 必须在
dragstart中调用event.dataTransfer.setData('text/plain', 'some-value'),哪怕只是空字符串 —— 这是 Safari/Chrome 的硬性要求 - 若拖的是图片或链接,浏览器可能自动启用内置拖拽(比如拖图到桌面),此时你的
dragstart可能根本没机会执行
drop 事件不触发?记得提前阻止 dragover 的默认行为
drop 事件永远不会触发,除非目标区域在 dragover 阶段显式调用了 event.preventDefault()。这是最常被忽略的一步,也是“明明写了 ondrop 却没反应”的元凶。
- 只监听
drop不够,必须同时监听dragover并在其中调用event.preventDefault() -
dragover会高频触发(类似mousemove),别在里面做重操作;单纯阻止默认即可 - 如果目标区是 等非可聚焦元素,还需加
event.dataTransfer.dropEffect = 'move'(可选,但有助于视觉反馈)怎么传自定义数据?
setData()和getData()类型必须严格匹配dataTransfer.setData('text/html', 'hi')存的数据,不能用getData('text/plain')读出来——类型不一致时返回空字符串,且无报错提示。