可行,但需手动处理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 位置。
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') 传轻量结构化数据。
立即学习“前端免费学习笔记(深入)”;
dragover 频繁触发问题,但 iOS Safari 仍不支持在非可编辑元素上触发 drop(需给列加 draggable="false" 或监听 touchstart 模拟)dataTransfer.setDragImage() 支持较弱,自定义拖拽图像容易失效,建议用 CSS ::-webkit-drag 配合透明占位更稳pointerdown/move/up + transform: translate 模拟真正难的不是拖拽动作本身,而是拖拽过程中实时判断插入位置、维持状态一致性、以及跨浏览器下 drag image 和 drop 区域的可靠性——这些细节不写死逻辑、不反复真机测试,上线后一定会出视觉错位或丢任务的问题。