如何用纯JavaScript实现中心面板内垂直可缩放子面板
实现中心面板内的垂直缩放功能
我目前有左、中、右三个支持水平缩放的面板,现在需要在中心面板内部新增一个面板,要求这个新面板能垂直缩放(可上下调整尺寸),并且必须使用纯JavaScript实现,不能破坏原有三个面板的水平缩放功能。
- 当前布局:左、中、右水平排列的三个面板,中心面板为单一区域
- 目标布局:中心面板被拆分为上下两个区域,中间有垂直拖拽条,可调整上下区域高度
现有代码
HTML
<div class="wrapper"> <div class="pane left"> This is the left pane. </div> <div class="pane center"> This is the center pane. <div class="gutter"></div> <div class="pane new"> This is the new pane. <div class="gutter_new"></div> </div> </div> <div class="pane right"> This is the right pane. <div class="gutter"></div> </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; } .center { position: relative; } .right { position: relative; flex-grow: 1; } .new { position: relative; } .gutter { width: 10px; height: 100%; background: #666; position: absolute; top: 0; left: 0; cursor: col-resize; } .gutter_new { height: 10px; width: 100%; background: #666; position: absolute; top: 0; left: 0; cursor: row-resize; }
JavaScript
const gutters = document.querySelectorAll(".gutter"); const gutter_orizontal = document.querySelectorAll(".gutter_new"); const panes = document.querySelectorAll(".pane"); const minWidth = 200; function resizer(e) { window.addEventListener("mousemove", mousemove); window.addEventListener("mouseup", mouseup); let prevX = e.x; const currentPane = e.currentTarget.parentNode; const currentPanel = currentPane.getBoundingClientRect(); const prevPane = currentPane.previousElementSibling; const prevPanel = prevPane.getBoundingClientRect(); function mousemove(e) { let newX = prevX - e.x; let newCurrentWidth = currentPanel.width + newX; let newPrevWidth = prevPanel.width - newX; if (newCurrentWidth < minWidth || newPrevWidth < minWidth) return; currentPane.style.width = newCurrentWidth + "px"; prevPane.style.width = newPrevWidth + "px"; } function mouseup() { window.removeEventListener("mousemove", mousemove); window.removeEventListener("mouseup", mouseup); } } gutters.forEach((gutter) => gutter.addEventListener("mousedown", resizer));
修改后的代码(实现垂直缩放)
调整HTML结构
将中心面板改为垂直布局容器,拆分出上下两个子面板:
<div class="wrapper"> <div class="pane left"> This is the left pane. </div> <div class="pane center vertical-container"> <div class="pane center-top"> This is the center top pane. </div> <div class="gutter-vertical"></div> <div class="pane center-bottom"> This is the center bottom pane. </div> <div class="gutter"></div> </div> <div class="pane right"> This is the right pane. <div class="gutter"></div> </div> </div>
更新CSS样式
给中心面板设置垂直flex布局,调整垂直拖拽条样式:
*, *::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; } /* 中心面板改为垂直flex容器 */ .vertical-container { display: flex; flex-direction: column; position: relative; } .center-top, .center-bottom { min-height: 100px; /* 设置最小高度,防止缩得太小 */ } .right { position: relative; flex-grow: 1; } /* 水平拖拽条 */ .gutter { width: 10px; height: 100%; background: #666; position: absolute; top: 0; left: 0; cursor: col-resize; } /* 垂直拖拽条 */ .gutter-vertical { height: 10px; width: 100%; background: #666; cursor: row-resize; }
新增垂直缩放的JavaScript逻辑
保留原有水平缩放功能,新增垂直拖拽处理逻辑:
const guttersHorizontal = document.querySelectorAll(".gutter"); const guttersVertical = document.querySelectorAll(".gutter-vertical"); const minWidth = 200; const minHeight = 100; // 垂直面板的最小高度 // 水平缩放逻辑(保留原有功能) function resizeHorizontal(e) { window.addEventListener("mousemove", mousemoveHorizontal); window.addEventListener("mouseup", mouseup); let prevX = e.x; const currentPane = e.currentTarget.parentNode; const currentPanel = currentPane.getBoundingClientRect(); const prevPane = currentPane.previousElementSibling; const prevPanel = prevPane.getBoundingClientRect(); function mousemoveHorizontal(e) { let newX = prevX - e.x; let newCurrentWidth = currentPanel.width + newX; let newPrevWidth = prevPanel.width - newX; if (newCurrentWidth < minWidth || newPrevWidth < minWidth) return; currentPane.style.width = newCurrentWidth + "px"; prevPane.style.width = newPrevWidth + "px"; } function mouseup() { window.removeEventListener("mousemove", mousemoveHorizontal); window.removeEventListener("mouseup", mouseup); } } // 垂直缩放逻辑 function resizeVertical(e) { window.addEventListener("mousemove", mousemoveVertical); window.addEventListener("mouseup", mouseup); let prevY = e.y; const gutter = e.currentTarget; const topPane = gutter.previousElementSibling; const bottomPane = gutter.nextElementSibling; const topPanelRect = topPane.getBoundingClientRect(); const bottomPanelRect = bottomPane.getBoundingClientRect(); function mousemoveVertical(e) { let newY = prevY - e.y; let newTopHeight = topPanelRect.height - newY; let newBottomHeight = bottomPanelRect.height + newY; if (newTopHeight < minHeight || newBottomHeight < minHeight) return; topPane.style.height = newTopHeight + "px"; bottomPane.style.height = newBottomHeight + "px"; } function mouseup() { window.removeEventListener("mousemove", mousemoveVertical); window.removeEventListener("mouseup", mouseup); } } // 绑定事件 guttersHorizontal.forEach(gutter => gutter.addEventListener("mousedown", resizeHorizontal)); guttersVertical.forEach(gutter => gutter.addEventListener("mousedown", resizeVertical));
关键改动说明
- HTML结构:将中心面板改造为垂直容器,拆分出上下两个子面板,中间添加垂直拖拽条
- CSS布局:给中心面板设置垂直flex布局,为上下子面板设置最小高度,调整垂直拖拽条样式
- JavaScript逻辑:
- 拆分原有水平缩放函数,保留原有功能不变
- 新增垂直缩放函数,计算鼠标垂直移动距离,动态调整上下面板高度,同时加入最小高度限制
- 分别为水平、垂直拖拽条绑定对应的事件处理函数
内容的提问来源于stack exchange,提问作者Nodigap
相关产品推荐
相关产品推荐

