Bac*_*uri 9 javascript css jquery flexbox css-transitions
我编写了一个脚本(在此处的用户的帮助下),它允许我扩展选定的 div 并使其他 div 相应地通过平均拉伸以适应剩余空间(宽度固定的第一个除外)而表现。
这是我想要实现的目标的图片:
为此,我使用 flex 和过渡。
它运行良好,但 jQuery 脚本指定了“400%”拉伸值(这非常适合测试)。
现在我希望选定的 div 扩展/收缩以完全适合内容而不是“400%”固定值。
我不知道我怎么能做到这一点。
是否可以 ?
我尝试克隆 div,使其适合内容,获取其值,然后使用此值进行转换,但这意味着我的初始宽度为百分比,但目标值以像素为单位。那行不通。
如果我以百分比形式转换像素值,那么无论出于何种原因,结果都不会完全适合内容。
在所有情况下,这似乎都是实现我想要的东西的复杂方法。
没有任何 flex 属性可以转换以适应所选 div 的内容吗?
这是代码(为了更好地阅读而进行了编辑/简化):
var expanded = '';
$(document).on("click", ".div:not(:first-child)", function(e) {
var thisInd =$(this).index();
if(expanded != thisInd) {
//fit clicked fluid div to its content and reset the other fluid divs
$(this).css("width", "400%");
$('.div').not(':first').not(this).css("width", "100%");
expanded = thisInd;
} else {
//reset all fluid divs
$('.div').not(':first').css("width", "100%");
expanded = '';
}
});Run Code Online (Sandbox Code Playgroud)
.wrapper {
overflow: hidden;
width: 100%;
margin-top: 20px;
border: 1px solid black;
display: flex;
justify-content: flex-start;
}
.div {
overflow: hidden;
white-space: nowrap;
border-right: 1px solid black;
text-align:center;
}
.div:first-child {
min-width: 36px;
background: #999;
}
.div:not(:first-child) {
width: 100%;
transition: width 1s;
}
.div:not(:first-child) span {
background: #ddd;
}
.div:last-child {
border-right: 0px;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Click on the div you want to fit/reset (except the first div)
<div class="wrapper">
<div class="div"><span>Fixed</span></div>
<div class="div"><span>Fluid (long long long long long text)</span></div>
<div class="div"><span>Fluid</span></div>
<div class="div"><span>Fluid</span></div>
</div>Run Code Online (Sandbox Code Playgroud)
这是jsfiddle:
https://jsfiddle.net/zajsLrxp/1/
编辑:这是我在大家的帮助下的工作解决方案(在窗口调整大小时更新的大小 + div 数和第一列的宽度动态计算):
var tableWidth;
var expanded = '';
var fixedDivWidth = 0;
var flexPercentage = 100/($('.column').length-1);
$(document).ready(function() {
// Set width of first fixed column
$('.column:first-child .cell .fit').each(function() {
var tempFixedDivWidth = $(this)[0].getBoundingClientRect().width;
if( tempFixedDivWidth > fixedDivWidth ){fixedDivWidth = tempFixedDivWidth;}
});
$('.column:first-child' ).css('min-width',fixedDivWidth+'px')
//Reset all fluid columns
$('.column').not(':first').css('flex','1 1 '+flexPercentage+'%')
})
$(window).resize( function() {
//Reset all fluid columns
$('.column').not(':first').css('flex','1 1 '+flexPercentage+'%')
expanded = '';
})
$(document).on("click", ".column:not(:first-child)", function(e) {
var thisInd =$(this).index();
// if first click on a fluid column
if(expanded != thisInd)
{
var fitDivWidth=0;
// Set width of selected fluid column
$(this).find('.fit').each(function() {
var c = $(this)[0].getBoundingClientRect().width;
if( c > fitDivWidth ){fitDivWidth = c;}
});
tableWidth = $('.mainTable')[0].getBoundingClientRect().width;
$(this).css('flex','0 0 '+ 100/(tableWidth/fitDivWidth) +'%')
// Use remaining space equally for all other fluid column
$('.column').not(':first').not(this).css('flex','1 1 '+flexPercentage+'%')
expanded = thisInd;
}
// if second click on a fluid column
else
{
//Reset all fluid columns
$('.column').not(':first').css('flex','1 1 '+flexPercentage+'%')
expanded = '';
}
});Run Code Online (Sandbox Code Playgroud)
body{
font-family: 'Arial';
font-size: 12px;
padding: 20px;
}
.mainTable {
overflow: hidden;
width: 100%;
border: 1px solid black;
display: flex;
margin-top : 20px;
}
.cell{
height: 32px;
border-top: 1px solid black;
white-space: nowrap;
}
.cell:first-child{
background: #ccc;
border-top: none;
}
.column {
border-right: 1px solid black;
transition: flex 0.4s;
overflow: hidden;
line-height: 32px;
text-align: center;
}
.column:first-child {
background: #ccc;
}
.column:last-child {
border-right: 0px;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<span class="text">Click on the header div you want to fit/reset (except the first one which is fixed)</span>
<div class="mainTable">
<div class="column">
<div class="cell"><span class="fit">Propriété</span></div>
<div class="cell"><span class="fit">Artisan 45</span></div>
<div class="cell"><span class="fit">Waterloo 528</span></div>
</div>
<div class="column">
<div class="cell"><span class="fit">Adresse</span></div>
<div class="cell"><span class="fit">Rue du puit n° 45 (E2)</span></div>
<div class="cell"><span class="fit">Chaussée de Waterloo n° 528 (E1)</span></div>
</div>
<div class="column">
<div class="cell"><span class="fit">Commune</span></div>
<div class="cell"><span class="fit">Ixelles</span></div>
<div class="cell"><span class="fit">Watermael-Boitsfort</span></div>
</div>
<div class="column">
<div class="cell"><span class="fit">Ville</span></div>
<div class="cell"><span class="fit">Marche-en-Famenne</span></div>
<div class="cell"><span class="fit">Bruxelles</span></div>
</div>
<div class="column">
<div class="cell"><span class="fit">Surface</span></div>
<div class="cell"><span class="fit">120 m<sup>2</sup></span></div>
<div class="cell"><span class="fit">350 m<sup>2</sup></span></div>
</div>
</div>Run Code Online (Sandbox Code Playgroud)
这是一个成熟的工作示例(样式+填充+更多数据):
https://jsfiddle.net/zrqLowx0/2/
谢谢你们 !
可以使用max-width和来解决它calc()。
首先,将CSS 中的 div 替换为 ,这样它们就会变大,在这种情况下效果更好width: 100%。flex: 1此外,使用过渡max-width。
现在,我们必须存储一些相关值:
divsLength可变) - 在本例中为 3。extraSpace变量)的总宽度 - 在本例中为 39px。有了这两个变量,我们可以为所有 div 设置默认值max-width(defaultMaxWidth变量),并在以后使用它们。这就是它们被全球存储的原因。
是defaultMaxWidth。calc((100% - extraSpace)/divsLength)
现在,让我们进入点击函数:
要展开 div,目标文本的宽度将存储在名为 的变量中,并将按其使用textWidth方式应用于 div (因为它返回浮点值)。max-width..getBoundingClientRect().width
对于其余的 div,将创建一个将应用于它们的calc()for 。
这是:。
计算的结果就是剩下的每个div应该有的宽度。max-widthcalc(100% - textWidth - extraScape)/(divsLength - 1)
当单击展开的 div(即恢复正常)时,默认值max-width将再次应用于所有.div元素。
var expanded = false,
divs = $(".div:not(:first-child)"),
divsLength = divs.length,
extraSpace = 39, //fixed width + border-right widths
defaultMaxWidth = "calc((100% - " + extraSpace + "px)/" + divsLength + ")";
divs.css("max-width", defaultMaxWidth);
$(document).on("click", ".div:not(:first-child)", function (e) {
var thisInd = $(this).index();
if (expanded !== thisInd) {
var textWidth = $(this).find('span')[0].getBoundingClientRect().width;
var restWidth = "calc((100% - " + textWidth + "px - " + extraSpace + "px)/" + (divsLength - 1) + ")";
//fit clicked fluid div to its content and reset the other fluid divs
$(this).css({ "max-width": textWidth });
$('.div').not(':first').not(this).css({ "max-width": restWidth });
expanded = thisInd;
} else {
//reset all fluid divs
$('.div').not(':first').css("max-width", defaultMaxWidth);
expanded = false;
}
});Run Code Online (Sandbox Code Playgroud)
.wrapper {
overflow: hidden;
width: 100%;
margin-top: 20px;
border: 1px solid black;
display: flex;
justify-content: flex-start;
}
.div {
overflow: hidden;
white-space: nowrap;
border-right: 1px solid black;
text-align:center;
}
.div:first-child {
min-width: 36px;
background: #999;
}
.div:not(:first-child) {
flex: 1;
transition: max-width 1s;
}
.div:not(:first-child) span {
background: #ddd;
}
.div:last-child {
border-right: 0;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
Click on the div you want to fit/reset (except the first div)
<div class="wrapper">
<div class="div"><span>Fixed</span></div>
<div class="div"><span>Fluid (long long long long text)</span></div>
<div class="div"><span>Fluid</span></div>
<div class="div"><span>Fluid</span></div>
</div>Run Code Online (Sandbox Code Playgroud)
这种方法的行为是动态的,并且应该适用于任何分辨率。
您需要硬编码的唯一值是extraSpace变量。