【问题标题】:Flexbox rows that maintain original height ratio on window resize在窗口调整大小时保持原始高度比的 Flexbox 行
【发布时间】:2016-05-13 16:09:03
【问题描述】:

我的项目的主要目标是拥有可调整大小的 flexbox div 视图。我为#v1#v2 工作了可调整大小的列。我也有可以调整大小的行,手柄是蓝色部分。现在我正在努力让行的高度在窗口高度发生变化时保持它们的高度比。 我的方法有什么问题/为什么不能按预期工作?

Heres the codepen I'm working in.

我的方法:使用 jQuery $(window).onResize() 。测量最后记录的高度和当前新高度之间的差值并计算差值。将此差异传递给名为resizeRows 的函数,该函数将计算的差异作为参数。 resizeRows 然后将差异拆分并添加到 3 行中。 逻辑可以在贴出的JS代码底部找到

问题:奇怪的行为。行似乎没有保持原来的高度比。

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="col-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="r1-r2-u-d" class="row-handle"></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 class="row-handle" id="r2-r3-u-d">
  </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>

JS

var mouseStartPosition = {};
var v1StartWidth, v2StartWidth, r1StartHeight, r2StartHeight, r3StartHeight;

var views_cntnr = document.getElementById('views-cntnr');
var views_cntnr_height = views_cntnr.offsetHeight;

// rows
var r1 = document.getElementById('r1');
var r2 = document.getElementById('r2');
var r3 = document.getElementById('r3');

// views
var v1 = document.getElementById('v1');
var v2 = document.getElementById('v2');

// handles
var r1_lr_handle = document.getElementById('r1-l-r');
var r1_r2_ud = document.getElementById('r1-r2-u-d');
var r2_r3_ud = document.getElementById('r2-r3-u-d');

r1_lr_handle.addEventListener("mousedown", mousedownR1LR);
r1_r2_ud.addEventListener("mousedown", mousedownR1R2UD);
r2_r3_ud.addEventListener("mousedown", mousedownR2R3UD);

var init_r1_ratio = 0.4;
var init_r2_ratio = 0.3;
var init_r3_ratio = 0.3;

initRowHeights();
function initRowHeights() {
  console.log(views_cntnr_height);
  r1.style.flexBasis = views_cntnr_height*init_r1_ratio + 'px';
  r2.style.flexBasis = views_cntnr_height*init_r2_ratio + 'px';
  r3.style.flexBasis = views_cntnr_height*init_r3_ratio + 'px';
}

/* V1 V2 WIDTH RESIZE */
function mousedownR1LR(e) {
  // get v1 width
  v1StartWidth = v1.offsetWidth;
  v2StartWidth = v2.offsetWidth;
  // get mouse position
  mouseStartPosition.x = e.pageX;
  mouseStartPosition.y = e.pageY;

  // add listeners for mousemove, mouseup
  window.addEventListener("mousemove", mousemoveR1LR);
  window.addEventListener("mouseup", mouseupR1LR);
}

function mousemoveR1LR(e) {
  var diff = mouseStartPosition.x - e.pageX;
  v1.style.flexBasis = v1StartWidth + -1 * diff + 'px';
  v2.style.flexBasis = v2StartWidth + diff + 'px';
}

function mouseupR1LR(e) {
  window.removeEventListener("mousemove", mousemoveR1LR);
  window.removeEventListener("mouseup", mouseupR1LR);
}

/* v1 v2 width resize */

/* R1 R2 HEIGHT RESIZE */
function mousedownR1R2UD(e) {
  // get R1 R2 height
  r1StartHeight = r1.offsetHeight;
  r2StartHeight = r2.offsetHeight;

  // get mouse position
  mouseStartPosition.x = e.pageX;
  mouseStartPosition.y = e.pageY;

  // add listeners for mousemove, mouseup
  window.addEventListener("mousemove", mousemoveR1R2UD);
  window.addEventListener("mouseup", mouseupR1R2UD);
}

function mousemoveR1R2UD(e) {
  var diff = mouseStartPosition.y - e.pageY;
  r1.style.flexBasis = r1StartHeight + -1 * diff + 'px';
  r2.style.flexBasis = r2StartHeight + 1 * diff + 'px';
}

function mouseupR1R2UD(e) {
  window.removeEventListener("mousemove", mousemoveR1R2UD);
  window.removeEventListener("mouseup", mouseupR1R2UD);
}

/* r1 r2 height resize */

/* R2 R3 HEIGHT RESIZE */
function mousedownR2R3UD(e) {
  // get R2 R3 height
  r2StartHeight = r2.offsetHeight;
  r3StartHeight = r3.offsetHeight;

  // get mouse position
  mouseStartPosition.x = e.pageX;
  mouseStartPosition.y = e.pageY;

  // add listeners for mousemove, mouseup
  window.addEventListener("mousemove", mousemoveR2R3UD);
  window.addEventListener("mouseup", mouseupR2R3UD);
}

function mousemoveR2R3UD(e) {
  var diff = mouseStartPosition.y - e.pageY;
  r2.style.flexBasis = r2StartHeight + -1 * diff + 'px';
}

function mouseupR2R3UD(e) {
  window.removeEventListener("mousemove", mousemoveR2R3UD);
  window.removeEventListener("mouseup", mouseupR2R3UD);
}

/* r2 r3 height resize */

function resizeRows(pixels) {
  var increase = pixels/3;
  r1.style.flexBasis = parseInt(r1.style.flexBasis) + increase + 'px';
  r2.style.flexBasis = parseInt(r2.style.flexBasis) + increase + 'px';
  r3.style.flexBasis = parseInt(r3.style.flexBasis) + increase + 'px';

};

$(window).resize(function() {
  var new_views_cntnr_height = views_cntnr.offsetHeight;
  var height_change = new_views_cntnr_height - views_cntnr_height;
  views_cntnr_height = new_views_cntnr_height;

  resizeRows(height_change);
});

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: 6px;
  cursor: col-resize;
}

.row-handle {
  background-color: DodgerBlue;
  height: 6px;
  cursor: row-resize;
}

/* handles */

/* ROWS */


/* ROW 1 */

#r1 {
  display: flex;
}

#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;
}


/* row 2 */


/* ROW 3 */

#r3 .view {
  border: #bfbfbf 1px solid;
  border-top: none;
  flex-grow: 1;
}

#r3 {
  display: flex;
}


/* row 3 */


/* rows */


/* views */

【问题讨论】:

  • 仅供参考,您的 codepen 链接返回 404 错误,并且您的 JavaScript 中混入了 CSS

标签: javascript jquery html flexbox


【解决方案1】:

我能够相当简单地完成效果 - codepen here.

确保为每一行分配一个 flex-basis,并使用 javascript 对其进行更改以实现拖动效果。在调整窗口大小时,元素会自动适应容器,因此您无需在调整窗口大小时大惊小怪。

HTML:

<div class="wrap">
  <div class="row" id="row-1">
    <div class="handle"></div>
    <div class="row-header"></div>
  </div>
  <div class="row" id="row-2">
    <div class="handle"></div>
    <div class="row-header"></div>
  </div>
  <div class="row" id="row-3">
    <div class="handle"></div>
    <div class="row-header"></div>
  </div>
</div>

CSS:

body {
  padding: 0;
  margin: 0;
}
.wrap {
  display: flex;
  flex-direction: column;
  background: white;
  height: 100vh;
}
.row {
  flex-basis: 100px;
  border: 4px solid #333;
  border-top: none;
}
.handle {
  height: 15px;
  background: lightblue;
  cursor: move;
}

Javascript:

$(document).ready(function(){  
  $('.row').mousedown(function(event){
    // They have dragged a row
    // Adjust the flex-basis of the previous row
    // Since index is 0 based and the rows are 1 based, use the index with the row to select the previous one

    var this_index = $(this).index()
    var selected_id = (this_index == 0) ? selected_id = '' : selected_id = '#row-' + this_index

    // Get starting flex-basis as int
    var starting_basis = $(selected_id).css('flex-basis')
    starting_basis = starting_basis.substr(0, starting_basis.length - 2)
    starting_basis = Number(starting_basis)

    var start_y = event.pageY

    $(document).mousemove(function(event){
      // Change flex basis as mouse moves
      y_pos = event.pageY - start_y

      var new_flex_basis = starting_basis + y_pos
      new_flex_basis += 'px'

      $(selected_id).css('flex-basis', new_flex_basis)
    })
  })

  $(document).mouseup(function(){
    $(document).off('mousemove')
  })
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-03-27
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 2013-09-01
    • 2020-04-23
    相关资源
    最近更新 更多