You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用纯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));

关键改动说明

  1. HTML结构:将中心面板改造为垂直容器,拆分出上下两个子面板,中间添加垂直拖拽条
  2. CSS布局:给中心面板设置垂直flex布局,为上下子面板设置最小高度,调整垂直拖拽条样式
  3. JavaScript逻辑:
    • 拆分原有水平缩放函数,保留原有功能不变
    • 新增垂直缩放函数,计算鼠标垂直移动距离,动态调整上下面板高度,同时加入最小高度限制
    • 分别为水平、垂直拖拽条绑定对应的事件处理函数

内容的提问来源于stack exchange,提问作者Nodigap

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 15:34:51