Javascript三面板拖拽调整问题:需实现指定联动与固定规则
三面板拖拽调整大小解决方案
原代码存在的问题
- 重复声明
centerPane变量,覆盖了右侧面板的引用 - 仅获取了一个
gutter元素,无法区分不同的拖拽边界 - 拖拽逻辑未实现面板间的联动,满足不了固定一侧面板的需求
- 使用静态的初始宽度值,拖拽时计算会出现偏差
修正后的完整代码
HTML
<div class="wrapper"> <div class="pane left"> This is the left pane. </div> <div class="gutter gutter-left"></div> <div class="pane center"> This is the center pane. </div> <div class="gutter gutter-right"></div> <div class="pane right"> This is the right pane. </div> </div>
CSS
*, *::before, *::after { box-sizing: border-box; } body { margin: 0; } .wrapper { height: 100vh; width: 100vw; background: #333; border: 6px solid #666; display: flex; } .pane { padding: 1em; color: #fff; min-width: 200px; width: 33.33%; /* 初始均分宽度,可按需调整 */ } .gutter { width: 10px; height: 100%; background: #666; cursor: col-resize; user-select: none; /* 防止拖拽时选中面板文字 */ }
JavaScript
const leftPane = document.querySelector(".left"); const centerPane = document.querySelector(".center"); const rightPane = document.querySelector(".right"); const gutterLeft = document.querySelector(".gutter-left"); const gutterRight = document.querySelector(".gutter-right"); // 通用拖拽处理函数,参数区分拖拽逻辑 function initResizer(gutter, adjustPane, linkedPane, isLeftFixed) { gutter.addEventListener('mousedown', (e) => { e.preventDefault(); // 防止默认行为干扰拖拽 const startX = e.clientX; const adjustWidth = adjustPane.offsetWidth; const linkedWidth = linkedPane.offsetWidth; function mousemove(e) { const deltaX = e.clientX - startX; let newAdjustWidth, newLinkedWidth; if (isLeftFixed) { // 左侧面板固定,调整中间和右侧 newAdjustWidth = adjustWidth + deltaX; newLinkedWidth = linkedWidth - deltaX; } else { // 右侧面板固定,调整左侧和中间 newAdjustWidth = adjustWidth + deltaX; newLinkedWidth = linkedWidth - deltaX; } // 限制最小宽度,避免面板过小 if (newAdjustWidth >= 200 && newLinkedWidth >= 200) { adjustPane.style.width = `${newAdjustWidth}px`; linkedPane.style.width = `${newLinkedWidth}px`; } } function mouseup() { // 拖拽结束移除事件监听 window.removeEventListener('mousemove', mousemove); window.removeEventListener('mouseup', mouseup); } window.addEventListener('mousemove', mousemove); window.addEventListener('mouseup', mouseup); }); } // 初始化左侧拖拽条:拖曳时调整左、中间面板,右侧固定 initResizer(gutterLeft, leftPane, centerPane, false); // 初始化右侧拖拽条:拖曳时调整中间、右侧面板,左侧固定 initResizer(gutterRight, centerPane, rightPane, true);
关键改进说明
- 拆分拖拽条为
gutter-left和gutter-right,明确对应左-中、中-右的边界 - 封装通用拖拽函数,通过参数快速切换不同的联动逻辑
- 在
mousedown时实时获取初始宽度和鼠标位置,避免静态值导致的计算偏差 - 添加最小宽度限制,确保面板不会被拖到无法正常显示的尺寸
- 修复了变量重复声明的低级错误,正确绑定所有元素的事件
内容的提问来源于stack exchange,提问作者Nodigap
相关产品推荐
相关产品推荐

