列宽拖拽需手动实现而非draggable属性:通过在列右边界添加拖拽手柄,监听mousedown/mousemove/mouseup(及对应touch事件),结合table-layout:fixed和getboundingclientrect()动态调整列宽。

draggable 属性本身不能实现列宽拖拽
直接给 <th> 或 <code><td> 加 <code>draggable="true",只会让整个单元格变成可拖放的“源”,和调整列宽完全无关。浏览器原生不支持用 draggable 控制表格列尺寸——它只参与 HTML5 拖放 API(dragstart/drop 等事件),不是 resize 机制。
真正可行的是监听 mousemove + 鼠标按下位置计算
核心思路是:在列右边界画一条竖直的“拖拽手柄”(常为 2px 宽的透明 div),监听 mousedown → mousemove → mouseup,动态修改左侧列的 width(或 style.width)。
- 必须阻止默认行为:
event.preventDefault()在mousemove中防止文本选中或滚动干扰 - 要用
getBoundingClientRect()获取列当前宽度和位置,避免依赖offsetWidth(可能受 box-sizing 影响) - 推荐监听
document上的mousemove和mouseup,而非仅 table 内部,防止鼠标快速移出时拖拽中断 - 列宽建议设为
px或vw等绝对单位;用%时需同步重算所有列占比,否则总和会溢出或不足
table-layout: fixed 是关键前提
如果没设 table-layout: fixed,浏览器会根据内容自动撑开列宽,你手动改 width 会被忽略。必须在 CSS 中显式声明:
table {
table-layout: fixed;
width: 100%;
}
th, td {
width: 120px; /* 初始宽度,后续可被 JS 覆盖 */
}
否则即使 JS 修改了 style.width,渲染结果也大概率不变。
移动端兼容需额外处理 touch 事件
PC 端靠 mousedown/mousemove,但 iOS/Android 必须补充 touchstart/touchmove/touchend,且注意:
-
touchmove默认可能触发页面滚动,要加event.preventDefault() - 触摸点坐标用
touches[0].clientX,不是clientX - 手柄区域建议最小宽度 24px,适配手指误触(
min-width: 24px) - 不要依赖
hover显示拖拽提示,移动端无 hover
列宽拖拽看着简单,但跨浏览器、跨设备时,事件绑定时机、坐标精度、CSS 渲染触发点这几个地方最容易卡住半天——尤其当表格嵌套在 flex 或 transform 容器里时,getBoundingClientRect() 返回值可能带偏移,得手动减去父容器的 scrollLeft 或 transform 偏移。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











