draggable属性是html5启用元素原生拖拽的布尔开关,需设为true并配合dragstart、dragover(必须preventdefault)、drop等事件才能实现完整拖拽功能。

在HTML5中,draggable 属性是启用元素原生拖拽能力的最基础方式。它本身只是个“开关”,设为 true 才允许该元素被鼠标拖动,但要真正实现拖拽交互(比如拖到目标区、交换位置、上传文件等),必须配合一组拖拽事件使用。
draggable 属性怎么写?
它是一个布尔属性,可取值为 true、false 或空字符串(等价于 true)。默认所有元素都是 draggable="false"(文本、图片等例外,浏览器有默认行为)。
<div draggable="true">可拖动的块</div><p draggable>空值也生效</p><span draggable="false">禁用拖拽</span>
光设 draggable 还不够:必须监听拖拽事件
设置 draggable="true" 后,元素只具备“被按下并移动”的能力,不自动触发任何逻辑。你需要手动绑定以下关键事件:
-
dragstart:拖拽开始时触发,常在这里用
dataTransfer.setData()存储拖拽数据(如文本、URL、自定义类型) -
dragover:拖拽过程中持续触发,**必须阻止默认行为(
e.preventDefault())**,否则目标区域无法接收 drop -
drop:在允许放置的目标上松开鼠标时触发,用
dataTransfer.getData()获取数据并执行业务逻辑 - 其他辅助事件:
drag、dragend、dragenter、dragleave可用于增强体验(如高亮目标区)
常见误区与注意事项
很多初学者以为设了 draggable="true" 就能“自动拖放”,结果发现没反应——多半卡在这几个点:
- 忘记在
dragover中调用e.preventDefault(),导致drop事件根本不会触发 - 在
dragstart中没设置dataTransfer数据,导致drop时取不到内容 - 对非可编辑元素(如
<div>)设 <code>draggable="true"是有效的;但对<input>、<textarea></textarea>等表单控件,浏览器默认禁用拖拽(即使显式设 true 也无效) - 移动端不支持原生 drag/drop API,需借助第三方库(如
interact.js)或模拟 touch 事件
一个最小可用示例
以下代码实现把一个 <div> 拖进另一个 <code><div> 并提示成功:
<pre class="brush:php;toolbar:false;"><div id="source" draggable="true">拖我</div>
<div id="target">拖到这里</div>
<script>
document.getElementById('source').addEventListener('dragstart', e => {
e.dataTransfer.setData('text/plain', 'hello from draggable');
});
const target = document.getElementById('target');
target.addEventListener('dragover', e => e.preventDefault()); // 关键!
target.addEventListener('drop', e => {
e.preventDefault();
alert('已放入:' + e.dataTransfer.getData('text/plain'));
});
</script></pre>
</div>










