使用原版 JavaScript 的自定义可调整大小的弹性框视图在鼠标按下时跳转

Custom resizable flexbox views using vanilla JavaScript jumps on mousedown

本文关键字:鼠标 视图 JavaScript 原版 自定义 可调整      更新时间:2023-09-26

我正在尝试使 4 个视图容器中的每一个都可以调整大小。我希望它类似于Codepen。我首先让 V1 和 V2 的宽度可调整大小。视图之间的蓝色边框是控点。当我将鼠标放在手柄 V2 的宽度上时,尺寸突然明显增加。为什么会这样?

我的实现背后的想法是计算鼠标按下和鼠标向上 x 坐标位置之间的差异,然后将此计算差异添加到容器的宽度(或技术上基于弹性(中。

这是我的代码笔。感谢您的任何帮助。

.HTML

<div id="views-cntnr">
  <div id="r1" class="view-row">
    <div id="v1" class="view">
      <div class="v-header">
        <button class="vh-btn v-settings"><i class="glyphicon glyphicon-cog"></i></button>
        <span class="v-title">R-Theta</span>
        <button class="vh-btn v-close"><i class="glyphicon glyphicon-remove"></i></button>
      </div>
    </div>
    <div class="handle" id="r1-l-r">
    </div>
    <div id="v2" class="view">
      <div class="v-header">
        <button class="vh-btn v-settings"><i class="glyphicon glyphicon-cog"></i></button>
        <span class="v-title">Cartesian</span>
        <button class="vh-btn v-close"><i class="glyphicon glyphicon-remove"></i></button>
      </div>
    </div>
  </div>
  <div id="r2" class="view-row">
    <div id="v3" class="view">
      <div class="v-header">
        <button class="vh-btn v-settings"><i class="glyphicon glyphicon-cog"></i></button>
        <span class="v-title">Longitudinal</span>
        <button class="vh-btn v-close"><i class="glyphicon glyphicon-remove"></i></button>
      </div>
    </div>
  </div>
  <div id="r3" class="view-row">
    <div id="v4" class="view">
      <div class="v-header">
        <span class="v-title">Console</span>
        <button class="vh-btn v-close"><i class="glyphicon glyphicon-remove"></i></button>
      </div>
    </div>
  </div>
</div>

.CSS

html,
body {
  height: 100%;
}
/* VIEWS */

/* VIEW HEADERS */
.v-header {
  position: relative;
  padding: 3px;
  border-bottom: #bfbfbf 1px solid;
  background-color: #1a1b1c;
  color: #ccc;
  font-weight: 900;
  font-size: 16px;
}
.v-title {
  position: relative;
  left: 35px;
}
#v4 .v-title {
  left: 6px;
}

/*VIEW BTNS */
.vh-btn {
  padding: 2px 8px;
  border-radius: 4px;
  font-size: 10px;
  background-color: #343436;
  color: white;
  border: black 1px solid;
  position: absolute;
  top: 4px;
}
.vh-btn:hover {
  background-color: #4d4d50;
}
.v-settings {
  left: 6px;
}
.v-close {
  right: 5px;
}

/* view btns */

/* view headers */
#views-cntnr {
  display: flex;
  flex-direction: column;
  height: 100%;
}
/* HANDLES */
#r1-l-r {
  background-color: DodgerBlue;
  width: 10px
}
/* handles */
/* ROWS */

/* ROW 1 */
#r1 {
  display: flex;
  flex-grow: 4;
}
#r1 .view {
  flex-grow: 1;
  border: #bfbfbf 1px solid;
  border-top: none;
  border-right: none;
}
#r1 .view:last-child {
  border-left: none;
}

/* row 1 */

/* ROW 2 */
#r2 .view {
  border: #bfbfbf 1px solid;
  border-top: none;
  flex-grow: 1;
}
#r2 {
  display: flex;
  flex-grow: 3;
}

/* row 2 */

/* ROW 3 */
#r3 .view {
  border: #bfbfbf 1px solid;
  border-top: none;
  flex-grow: 1;
}
#r3 {
  display: flex;
  flex-grow: 2;
}

/* row 3 */

/* rows */

/* views */

.JS

var mouseStartPosition = {};
var v1StartWidth;
var v1 = document.getElementById('v1');
var v2 = document.getElementById('v2');
var r1_lr_handle = document.getElementById('r1-l-r');
r1_lr_handle.addEventListener("mousedown", mousedownR1RL);
function mousedownR1RL(e) {
  // get v1 width
  v1StartWidth = v1.offsetWidth;
  // get mouse position
  mouseStartPosition.x = e.pageX;
  mouseStartPosition.y = e.pageY;
  console.log('start... x:', mouseStartPosition.x, 'y:', mouseStartPosition.y);
  // add listeners for mousemove, mouseup
  window.addEventListener("mousemove", mousemove);
  window.addEventListener("mouseup", mouseup);
}
function mousemove(e) {
  console.log('mouse move... x:', e.pageX, 'y:', e.pageY);
  var diff = mouseStartPosition.x - e.pageX;
  v2.style.flexBasis = v1StartWidth + diff + 'px';
}
function mouseup(e) {
  window.removeEventListener("mousemove", mousemove);
  window.removeEventListener("mouseup", mouseup);
}

尝试更新两个框的大小。当您只更新一个时,浏览器会尝试增大未更新的框。它适用于JS上的这个小更新。

var mouseStartPosition = {};
var v1StartWidth;
var v2StartWidth;
var v1 = document.getElementById('v1');
var v2 = document.getElementById('v2');
var r1_lr_handle = document.getElementById('r1-l-r');
r1_lr_handle.addEventListener("mousedown", mousedownR1RL);
function mousedownR1RL(e) {
  // get v1 width
  v1StartWidth = v1.offsetWidth;
  v2StartWidth = v2.offsetWidth;
  // get mouse position
  mouseStartPosition.x = e.pageX;
  mouseStartPosition.y = e.pageY;
  console.log('start... x:', mouseStartPosition.x, 'y:', mouseStartPosition.y);
  // add listeners for mousemove, mouseup
  window.addEventListener("mousemove", mousemove);
  window.addEventListener("mouseup", mouseup);
}
function mousemove(e) {
  // console.log('mouse move... x:', e.pageX, 'y:', e.pageY);
  var diff = mouseStartPosition.x - e.pageX;
    v1.style.flexBasis = v1StartWidth + -1*diff + 'px';
    v2.style.flexBasis = v2StartWidth + diff + 'px';
}
function mouseup(e) {
  window.removeEventListener("mousemove", mousemove);
  window.removeEventListener("mouseup", mouseup);
}