我有一个可以通过拖动调整大小的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>
&#13;
首选纯CSS解决方案。解决方案应该允许缩小容器,使所有物品都处于最小尺寸,并扩展它以使它们全部占据它们的最大尺寸。 在容器的CSS中硬编码最小和最大高度是不可接受的。我正在寻找通用的解决方案。
答案 0 :(得分:1)
我不认为这里可以使用纯CSS解决方案,因为你绝对使用JavaScript来设置高度。
您可以在下面的代码段中添加一个像我所做的那样的警卫。当可调整大小为零时,你也可以计算底部高度,当它是巨大的时候,并根据它来引入边界(可能性能更好,但dom更改不好)
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>