在窗口上保持原始高度比例的Flexbox行调整大小 [英] Flexbox rows that maintain original height ratio on window resize

查看:111
本文介绍了在窗口上保持原始高度比例的Flexbox行调整大小的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

继承我正在使用的codepen。



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



问题:奇怪的行为。行不会保持原来的高度比例。


$ b

HTML



  < div id =views-cntnr> 
< div id =r1class =view-row>
< div id =v1class =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-handleid =r1-l-r>
< / div>
< div id =v2class =view>
< div class =v-header>
< button class =vh-btn v-settings>< i class =glyphicon glyphicon-cog>< / i>< / button>
< span class =v-title>笛卡尔< / span>
< button class =vh-btn v-close>< i class =glyphicon glyphicon-remove>< / i>< / button>
< / div>
< / div>
< / div>
< div id =r1-r2-u-dclass =row-handle>< / div>
< div id =r2class =view-row>
< div id =v3class =view>
< div class =v-header>
< button class =vh-btn v-settings>< i class =glyphicon glyphicon-cog>< / i>< / button>
< span class =v-title>纵向< / span>
< button class =vh-btn v-close>< i class =glyphicon glyphicon-remove>< / i>< / button>
< / div>
< / div>
< / div>
< div class =row-handleid =r2-r3-u-d>
< / div>
< div id =r3class =view-row>
< div id =v4class =view>
< div class =v-header>
< span class =v-title>控制台< / 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');

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

//句柄
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();
函数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 * /
功能mousedownR1LR(E){
//获取V1宽度
v1StartWidth = v1.offsetWidth;
v2StartWidth = v2.offsetWidth;
//获取鼠标位置
mouseStartPosition.x = e.pageX;
mouseStartPosition.y = e.pageY;

//为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);

$ b / * v1 v2 width resize * /

/ * R1 R2 HEIGHT RESIZE * /
function mousedownR1R2UD(e){
//获得R1 R2高度
r1StartHeight = r1.offsetHeight;
r2StartHeight = r2.offsetHeight;

//获取鼠标位置
mouseStartPosition.x = e.pageX;
mouseStartPosition.y = e.pageY;

//为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);

$ b $ * r1 r2 height resize * /

/ * R2 R3 HEIGHT RESIZE * /
function mousedownR2R3UD(e){
//获得R2 R3高度
r2StartHeight = r2.offsetHeight;
r3StartHeight = r3.offsetHeight;

//获取鼠标位置
mouseStartPosition.x = e.pageX;
mouseStartPosition.y = e.pageY;

//为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';

};

$(窗口).resize(函数(){
变种new_views_cntnr_height = views_cntnr.offsetHeight;
变种height_change = new_views_cntnr_height - views_cntnr_height;
views_cntnr_height = new_views_cntnr_height;

resizeRows(height_change);
});

html,
body {
height:100%;
}

/ * VIEWS * /



/ *观看片段* /

.v -header {
position:relative;
padding:3px;
border-bottom:#bfbfbf 1px solid;
背景颜色:#1a1b1c;
color:#ccc;
font-weight:900;
font-size:16px;
}

.v-title {
position:relative;
left:35px;
}

#v4 .v-title {
left:6px;
}


/ *查看BTNS * /

.vh-btn {
padding:2px 8px;
border-radius:4px;
font-size:10px;
背景颜色:#343436;
颜色:白色;
border:black 1px solid;
position:absolute;
top:4px;
}

.vh-btn:hover {
background-color:#4d4d50;
}

.v-settings {
left:6px;
}

.v-close {
right:5px;


$ b $ * b





$ b $ views-cntnr {
display:flex;
flex-direction:column;
身高:100%;
}

/ * HANDLES * /

#r1 -l-r {
background-color:DodgerBlue;
width:6px;
cursor:col-resize;
}

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

$ b $ *把手* /

* * 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;


$ b / *第1行* /


/ *第2行* /

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

#r2 {
display:flex;


$ b / *第2行* /


/ *行3 * /

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

#r3 {
display:flex;


$ b / *第3行* /


/ *行* /


/ * views * /


解决方案

完成的效果相当简单 - codepen这里



确保你为每一行分配一个弹性基础,改变它与JavaScript来完成拖动效果。在窗口调整大小的元素将适合自己的容器自动,所以你不需要大惊小怪与窗口。



HTML:

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

CSS:

  body {
padding:0;
保证金:0;
}
.wrap {
display:flex;
flex-direction:column;
背景:白色;
身高:100vh;
}
.row {
flex-basis:100px;
border:4px solid#333;
border-top:none;
}
.handle {
height:15px;
background:lightblue;
cursor:move;

$ / code $ / $ p



 $(document).ready(function(){
$('。row')。mousedown(function(event){
// they have dragged a row
//调整前一行的基于flex的元素
//由于索引为0,行为1,所以使用索引来选择前一行

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

//开始flex-basis为int
var starting_basis = $(selected_id).css('flex-basis')
starting_basis = starting_basis.substr(0,starting_basis.length - 2)
start_basis = Number(starting_basis)

var start_y = event.pageY
$ b $(document).mousemove(function(event){
//更改弹性基础当鼠标移动
y_pos = event.pageY - start_y

var new_flex_basis = starting_basis + Y_POS
new_flex_basis + = '像素'

$(selected_id)的CSS( '挠曲基础',new_flex_basis)
})
})

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


My main goal with my project is to have resizable flexbox div views. I have working resizable columns for #v1 and #v2. I also have rows that can be resized, the handles are the blue part. Now Im working on have the height of the rows maintain their height ratio when the window height changes. Whats wrong with my approach/ why isnt it working as expected?

Heres the codepen I'm working in.

My approach: Use jQuery $(window).onResize() . Measure that difference between the last recorded height and the current new height and calculate the difference. Pass this difference to a function called resizeRows which takes the difference calculated as a parameter. resizeRows then splits the difference in and adds it amongst the 3 rows. Logic can be found at the bottom of JS code posted.

Issues: Strange behavior. Rows dont appear to maintain their original height ratios.

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 */

解决方案

I was able to accomplish the effect fairly simply - codepen here.

Make sure you assign a flex-basis to each row, altering it with javascript to accomplish the dragging effect. On window resize the elements will fit themselves to the container automatically, so you don't need to fuss with window on resize.

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')
  })
})

这篇关于在窗口上保持原始高度比例的Flexbox行调整大小的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆