javascript实现拖拽需设draggable="true"、在dragstart中用setdata()传字符串数据、在dragover中preventdefault()启用投放,drop时再preventdefault()并用getdata()接收。

在 JavaScript 中实现拖拽,关键在于正确设置 dragstart 和 drop 事件,并配合其他必要事件(如 dragover)才能让整个流程生效。默认情况下,浏览器会阻止大多数元素的拖放行为,所以必须显式处理。
让元素可拖拽:设置 draggable 属性
只有设置了 draggable="true" 的元素才能触发 dragstart:
<div id="drag-item" draggable="true">拖我</div>
注意:<img> 和 <a></a> 默认可拖拽,但其他元素(如 <div>)必须手动加属性。
<h3>在 dragstart 中设置拖拽数据</h3>
<p><code>dragstart 是拖拽开始时触发的事件,必须在这里调用 event.dataTransfer.setData(),否则 drop 无法获取有效数据:
- 第一个参数是数据类型(常用
"text/plain"或自定义如"application/my-item") - 第二个参数是实际要传递的数据(字符串)
- 可同时设置多个类型,便于接收方判断兼容性
document.getElementById("drag-item").addEventListener("dragstart", (e) => {
e.dataTransfer.setData("text/plain", "hello from drag-item");
// 可选:设置拖拽时显示的图片(提升体验)
e.dataTransfer.setDragImage(e.target, 0, 0);
});
允许目标区域接收拖拽:必须阻止 dragover 默认行为
即使绑定了 drop,如果没处理 dragover,浏览器会拒绝投放。只需在该事件中调用 e.preventDefault() 即可启用投放:
const dropZone = document.getElementById("drop-zone");
dropZone.addEventListener("dragover", (e) => {
e.preventDefault(); // 关键!否则 drop 不会触发
});
dropZone.addEventListener("drop", (e) => {
e.preventDefault(); // 同样需要,避免跳转或打开文件等默认行为
const data = e.dataTransfer.getData("text/plain");
console.log("接收到:", data); // 输出 "hello from drag-item"
// 此处可插入 DOM 操作,比如追加、移动、复制等逻辑
});
常见问题与补充说明
-
drop事件只在dragover被阻止后才触发,缺一不可 -
dataTransfer只支持字符串类型数据;如需传对象,请先JSON.stringify() - 跨 iframe 或跨窗口拖拽受限于同源策略
- 移动端不支持原生 drag/drop API,需用 touch 事件模拟











