一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

HTML怎么做看板布局_html看板Kanban拖拽布局实现纯干货

时间:2026-06-22 10:07:52 编辑:袖梨 来源:一聚教程网

用 CSS Grid 实现响应式看板:grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)) 实现等宽自适应列,每列 overflow-y: auto、min-height: 60vh,禁用 grid-gap 改用 padding;拖拽需全程 preventDefault(),动态插入 pointer-events: none 占位符辅助定位;iOS 需降级为 touch 事件模拟。

用 CSS Grid 实现响应式看板容器,别碰 float 或 inline-block

纯 CSS 实现 Kanban 列布局,核心是让每列(column)等宽、自适应、可滚动,同时列内卡片垂直堆叠。用 display: grid 配合 grid-template-columns 最稳妥,避免老式布局带来的高度塌陷、间隙错位问题。

常见错误:用 float: left 拼列,结果在 Safari 下列宽计算异常;或用 inline-blockvertical-align,导致列间基线对齐错乱、空格吃宽度。

  • grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)) —— 自动适配列数,最小列宽 280px,最大均分剩余空间
  • 每列设 overflow-y: auto,保证长列表可滚动而不撑高整页
  • 列容器加 min-height: 60vh,防止空列塌缩看不见拖拽区
  • 禁用 grid-gap 改用 padding 控制列间距,避免 gap 在拖拽时干扰 DragEvent 坐标判断

给卡片加 draggable="true" 后必须拦截默认行为

HTML5 原生拖拽 API 看似简单,但不处理默认行为会导致:拖动瞬间页面文字被选中、图片被拖出浏览器、松手后卡片“消失”(其实是被浏览器当文件下载了)。

关键点在于所有拖拽相关事件都必须调用 event.preventDefault(),否则 drop 事件根本不会触发。

立即学习“前端免费学习笔记(深入)”;

  • 在卡片上监听 dragstart,设 event.dataTransfer.setData('text/plain', cardId),只传 ID,别传 DOM 节点
  • 列容器监听 dragover,必须立刻 event.preventDefault(),否则 drop 不会触发
  • 列容器监听 drop,用 event.dataTransfer.getData('text/plain') 拿到 ID,再用 appendChildinsertBefore 移动真实 DOM 节点
  • 别在 dragenter 里做 heavy work(比如重排卡片),它可能高频触发,造成卡顿

跨列拖拽时,目标列的 drop 事件坐标不可靠

原生 drop 事件只告诉你“落在哪个元素上”,但不知道该插在目标列的第几个位置——尤其当列内卡片高度不一时,靠 clientY 算序号容易误判。

更可靠的做法是监听 dragover 时动态插入一个占位符(div.placeholder),并实时调整它的位置,让用户看到“将插入此处”的视觉反馈。

  • dragover 中,遍历目标列内所有卡片,用 getBoundingClientRect() 比较 event.clientY 和每个卡片中线,决定 placeholder 插入点
  • placeholder 必须设 pointer-events: none,否则会拦截后续拖拽事件
  • 每次 dragover 触发前先移除旧 placeholder,避免残留多个
  • 松手(drop)后立即移除 placeholder,再执行真实 DOM 移动

移动端 Safari 的拖拽支持几乎为零,必须降级为触摸模拟

iOS / iPadOS 的 Safari 完全不支持 draggable="true" 和相关事件,连 dragstart 都不会触发。强行依赖原生 API 会导致整个功能在 iPhone 上完全不可用。

必须单独检测 'ontouchstart' in windownavigator.maxTouchPoints > 0,启用基于 touchstart/touchmove/touchend 的模拟逻辑。

  • touchstart 记录起始卡片和初始触摸点,禁用默认行为(event.preventDefault())防止滚动
  • touchmove 动态更新卡片位置(transform: translate3d),并实时计算当前列和插入点
  • touchend 触发真实移动,此时需手动触发一次 drop 类似逻辑
  • 注意 iOS 的 touchmove 默认会触发页面滚动,务必在绑定时加 { passive: false }

拖拽看似只是“拖过去”,但跨浏览器兼容、跨设备交互、视觉反馈与 DOM 同步这三块,任一环节漏掉细节,用户就会觉得“卡”“不准”“点了没反应”。尤其是 placeholder 的插入时机和 touch 事件的 passive 设置,线上最容易被忽略。

热门栏目