可行,但需手动处理dragstart、dragover、drop事件;dragover必须preventDefault()才能触发drop,否则显示禁止图标;跨列移动需用dataTransfer存源信息,列内排序须动态计算插入点。

直接用 HTML5 Drag and Drop API 做多列看板,不引入框架是可行的,但必须手动处理 dragstart、dragover、drop 三个核心事件,且默认不支持跨列排序和视觉反馈——这是绝大多数人卡住的第一关。
为什么 dragover 必须阻止默认行为?
浏览器对 drop 事件有严格限制:只有在目标元素触发了 dragover 并调用了 event.preventDefault(),drop 才会被触发。否则拖拽到列上会变成“禁止图标”,松手没反应。
- 漏写
event.preventDefault()是最常见错误,尤其在监听dragover时只写了console.log却忘了阻止默认 - 不能只在
drop里阻止,默认行为必须在dragover阶段就禁掉 -
dragenter不可靠,部分浏览器不触发,别依赖它来设样式或标记区域
如何让卡片在列内拖拽排序,又支持跨列移动?
关键在于区分“列内重排”和“跨列搬运”两种逻辑,靠 dataTransfer 存储源信息,而不是 DOM 位置。
生成可在 deepbi 沙箱 iframe 内运行或作为独立文件运行的交互式 HTML 页面,使用 `window.deepbi` JS SDK 实现数据查询、空间管理、文件浏览及用户操作。当用户提出以下需求时启用该能力: - 创建 KPI 仪表盘、数据表格、文件浏览器、成员列表、管理页面; - 明确要求“转成 dhtml”、“转译成 HTML”、“把 XX 页面转成……”、“控制台页面”、“管理后台”、“DeepBI 页面迁移”; - 提及位于 `apps/console/src/featur
- 在
dragstart中用event.dataTransfer.setData('text/plain', JSON.stringify({id: cardId, column: currentColumnId}))记录原始归属 -
drop时读取目标列 ID,再根据是否同列决定是插入排序还是移动 DOM 节点 - 列内排序需计算鼠标相对于目标列中已有卡片的位置(可用
getBoundingClientRect()+clientY判断插入点) - 不要用
insertBefore直接插进父节点开头/结尾,要动态找最近的兄弟节点做参照
DragEvent 的兼容性坑有哪些?
dataTransfer.items 在 Safari 和旧版 Edge 中行为不一致,且不支持自定义 MIME 类型;稳妥做法是只用 dataTransfer.getData('text/plain') 传轻量结构化数据。
- Safari 15+ 修复了
dragover频繁触发问题,但 iOS Safari 仍不支持在非可编辑元素上触发drop(需给列加draggable="false"或监听touchstart模拟) - Firefox 对
dataTransfer.setDragImage()支持较弱,自定义拖拽图像容易失效,建议用 CSS::-webkit-drag配合透明占位更稳 - 移动端基本不可用原生 DnD,如果需兼容触屏,得 fallback 到
pointerdown/move/up+transform: translate模拟
真正难的不是拖拽动作本身,而是拖拽过程中实时判断插入位置、维持状态一致性、以及跨浏览器下 drag image 和 drop 区域的可靠性——这些细节不写死逻辑、不反复真机测试,上线后一定会出视觉错位或丢任务的问题。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










