2016-07-24 68 views
2

我有一个flexbox容器,可以通过拖动调整大小。如何防止容器溢出(变得太小并开始隐藏某些项目)或下溢(变得太大并显示空白)?如何防止柔性容器溢出/下溢?

在以下示例中,当所有项目达到18px高度(除最后一个项目之外)时,容器应停止收缩,并在所有项目达到其最大高度(不应出现空白区域)时停止展开。

const resizable = document.querySelector('.flex'); 
 
let startHeight = NaN; 
 
let startY = NaN; 
 

 
resizable.addEventListener('mousedown', e => { 
 
    startHeight = resizable.getBoundingClientRect().height; 
 
    startY = e.pageY; 
 
}); 
 

 
window.addEventListener('mousemove', e => { 
 
    if (isNaN(startY) || isNaN(startHeight)) { 
 
    return; 
 
    } 
 
    
 
    resizable.style.height = (startHeight + e.pageY - startY) + 'px'; 
 
}); 
 

 
window.addEventListener('mouseup',() => { 
 
    startHeight = startY = NaN; 
 
});
.flex { 
 
    display: flex; 
 
    flex-direction: column; 
 
    overflow: hidden; 
 
    border: 1px solid black; 
 
    cursor: ns-resize; 
 
    -webkit-user-select: none; 
 
    -moz-user-select: none; 
 
    -ms-user-select: none; 
 
    user-select: none; 
 
} 
 

 
.item-1 { 
 
    background: red; 
 
    height: 40px; 
 
    max-height: 60px; 
 
    flex: 1; 
 
} 
 

 
.item-2 { 
 
    background: blue; 
 
    flex: none; 
 
} 
 

 
.item-3 { 
 
    background: green; 
 
    height: 50px; 
 
    max-height: 50px; 
 
    flex: 1; 
 
} 
 

 
.item-4 { 
 
    background: yellow; 
 
    height: 30px; 
 
    flex: none; 
 
}
<div class="flex"> 
 
    <div class="item-1"> 
 
    Item 1 
 
    </div> 
 
    <div class="item-2"> 
 
    Item 2 
 
    </div> 
 
    <div class="item-3"> 
 
    Item 3 
 
    </div> 
 
    <div class="item-4"> 
 
    Item 4 
 
    </div> 
 
</div>

纯CSS的解决方案将是优选的。解决方案应该允许收缩容器,以便所有物品达到其最小尺寸,并扩大容器使其全部占据其最大尺寸。 在容器的CSS中对最小高度和最大高度进行硬编码是不可接受的。我正在寻求一个通用的解决方案。

+0

基础上(可能是更好的性能,但不好用DOM变化)边界你见过这个库? http://isotope.metafizzy.co/ –

+1

我对此并不了解,但乍看之下,它看起来像一个砌体式布局的图书馆,不是吗?你能否详细说明如何解决这个问题?谢谢。 :) – matteodelabre

+0

随着你的flex,设置 最小高度:100px; max-height:200px; 如果你想要更高级的东西,你可以使用我建议的库:) –

回答

1

我不认为纯粹的CSS解决方案是可行的,因为你绝对使用JavaScript来设置高度。

你可以像我在下面的代码段中所做的那样添加一个警卫。你也可以计算出底部的高度时,可调整大小的大小为零时,它的巨大和引进

const resizable = document.querySelector('.flex'); 
 
const lastChild = resizable.querySelector(':last-child'); 
 
const resizableBorderBottom = 1; // hardcoded - could be computed too 
 
let startHeight = NaN; 
 
let startY = NaN; 
 

 
resizable.addEventListener('mousedown', e => { 
 
    /* 
 
    * here we assume that the bottom of the last child 
 
    * is the same as the bottom of the resizable for simplicity 
 
    */ 
 
    startHeight = resizable.getBoundingClientRect().height; 
 
    startY = e.pageY; 
 
}); 
 

 
window.addEventListener('mousemove', e => { 
 
    if (isNaN(startY) || isNaN(startHeight)) { 
 
    return; 
 
    } 
 
    const lastHeight = resizable.style.height; 
 
    resizable.style.height = ((startHeight + e.pageY - startY) | 0) + 'px'; 
 
    const lastChildBottom = lastChild.getBoundingClientRect().bottom | 0; 
 
    const resizableBottom = (resizable.getBoundingClientRect().bottom | 0) - resizableBorderBottom; 
 
    // check if we need to revert the change 
 
    if (lastChildBottom !== resizableBottom) { 
 
    resizable.style.height = lastHeight; 
 
    } 
 
}); 
 

 
window.addEventListener('mouseup',() => { 
 
    startHeight = startY = NaN; 
 
});
.flex { 
 
    display: flex; 
 
    flex-direction: column; 
 
    overflow: hidden; 
 
    border: 1px solid black; 
 
    cursor: ns-resize; 
 
    -webkit-user-select: none; 
 
    -moz-user-select: none; 
 
    -ms-user-select: none; 
 
    user-select: none; 
 
} 
 

 
.item-1 { 
 
    background: red; 
 
    height: 40px; 
 
    max-height: 60px; 
 
    flex: 1; 
 
} 
 

 
.item-2 { 
 
    background: blue; 
 
    flex: none; 
 
} 
 

 
.item-3 { 
 
    background: green; 
 
    height: 50px; 
 
    max-height: 50px; 
 
    flex: 1; 
 
} 
 

 
.item-4 { 
 
    background: yellow; 
 
    height: 30px; 
 
    flex: none; 
 
}
<div class="flex"> 
 
    <div class="item-1"> 
 
    Item 1 
 
    </div> 
 
    <div class="item-2"> 
 
    Item 2 
 
    </div> 
 
    <div class="item-3"> 
 
    Item 3 
 
    </div> 
 
    <div class="item-4"> 
 
    Item 4 
 
    </div> 
 
</div>

+0

没有想过检查最后一个孩子的位置。非常聪明的解决方案。非常感谢! :) – matteodelabre