div的宽度。它发生巨大变化

时间:2019-06-18 14:23:13

标签: jquery html css

我想设置.center的宽度。我有不同的行,有些带有按钮,有些则没有。由于动态加载,每行.center的宽度应该不同。

在示例中,第一行的.center应该是centerWidth2
第二行的.center应该是centerWidth1

这就是我想要的样子。问题是我不知道.right何时可见。 (因此,当.right可见时,我希望.center变短并自动执行。)

var centerWidth1 =  $('#wrap').width();
var centerWidth2 =  $('#wrap').width()-55;

$("#first").css('width', centerWidth2);
$("#second").css('width', centerWidth1);
#wrap {
	position: relative;
	margin: 20px auto;
	width: 80%;
	background-color: red;
}
	
.row {
	position: relative;
	height: 30px;
	margin-bottom: 10px;
}
	
.center {
	float:left;
	min-height: 30px; line-height: 30px;
	display: inline-block;
	text-align: center;
	background-color: blue;
}

.right {
	float:left;
	width: 50px; height: 30px; line-height: 30px;
	display: inline-block;
	text-align: center;
	margin-left: 5px;
	border:0;
	background-color: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div id="wrap">
	<div class="row">
		<div class="center" id="first">center</div>
		<div class="right">right</div>	
	</div>
	<div class="row">
		<div class="center" id="second">center</div>
	</div>
</div>

2 个答案:

答案 0 :(得分:2)

为实现您的解决方案,我使用了.each()在各行之间循环。然后,我使用.row>检查每个.right来查看right.length > 0元素是否存在。它确实存在,因为.row我将.right元素的宽度减去#wrap的宽度,并将其应用于.center。如果该行中不存在.right,那么我就应用#wrap的宽度。

P.S。我还使用margin-left:5px;来获取.right上的right.css('marginLeft').replace('px', '')来获得余量左边值并从宽度中减去它。

我建议虽然只使用flex。 (请参阅以下示例之后的下一个示例)

// Get the outer width of #wrap
var centerWidth =  $('#wrap').outerWidth();

// Loop through each .row
$('.row').each(function() {
  // Attempt to get the .right element in currently looped .row
  var right = $(this).find('.right');
  // Assign the outer width of #wrap to the width variable
  var width = centerWidth;
  // Check if the .right element exists in currently looped .row
  if(right.length > 0) {
    // If the .right element exists subtract the outer width and the margin left value of .right from the outer width of #wrap and assign the value to the width of .center
    width = parseFloat(width - right.outerWidth() - right.css('marginLeft').replace('px', ''));
  }
  // Otherwise assign the outer width of #wrap to .center
  $(this).find('.center').css('width', width);
});
#wrap {
	position: relative;
	margin: 20px auto;
	width: 80%;
	background-color: red;
}
	
.row {
	position: relative;
	height: 30px;
	margin-bottom: 10px;
}
	
.center {
	float:left;
	min-height: 30px; line-height: 30px;
	display: inline-block;
	text-align: center;
	background-color: blue;
}

.right {
	float:left;
	width: 50px; height: 30px; line-height: 30px;
	display: inline-block;
	text-align: center;
	margin-left: 5px;
	border:0;
	background-color: grey;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
<div id="wrap">
	<div class="row">
		<div class="center" id="first">center</div>
		<div class="right">right</div>	
	</div>
	<div class="row">
		<div class="center" id="second">center</div>
	</div>
</div>


替代Flex解​​决方案

这是一个简单得多的解决方案,并且使用的处理能力要低得多。

/* FLEX CSS START */
.row {
  display:flex;
}
.center {
  flex-grow:1;
}
.right {
  flex-shrink:1;
}
/* FLEX CSS END */
#wrap {
  margin: 20px auto;
  width: 80%;
  background-color: red;
}

.row {
  height: 30px;
  margin-bottom: 10px;
}

.center {
  min-height: 30px; 
  line-height: 30px;
  text-align: center;
  background-color: blue;
}

.right {
  width: 50px; 
  height: 30px; 
  line-height: 30px;
  text-align: center;
  margin-left: 5px;
  background-color: grey;
}
<div id="wrap">
	<div class="row">
		<div class="center" id="first">center</div>
		<div class="right">right</div>	
	</div>
	<div class="row">
		<div class="center" id="second">center</div>
	</div>
</div>

答案 1 :(得分:1)

由于您说您不知道是否会存在一个.right元素,所以我假设您正在计划一个供用户执行某项功能的功能,并且该元素将从该行出现或消失。就是说,我的建议是将该元素保留在文档中,但要在是否作为页面流的一部分之间进行切换。我们该怎么做?与display: none一起使用,这也是我们的.is(":visible")会将其评估为false的值,因为诸如visibility: hiddenoppacity: 0.0之类的其他任何因素都将被评估为true ,因为它们仍然在页面流中,尽管您实际上看不到它们。如果您完全删除元素,我提供给您的脚本也可以使用,因为它找不到要评估的元素,但是我认为这样会更好。

下面是一个包含四行的示例,在.right元素上具有备用状态只是为了可视化最终结果:

<!DOCTYPE html>
<html>
    <head>
        <title>Dynamic center</title>
        <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.0/jquery.min.js"></script>
    </head>
    <body>
        <div id="wrap">
            <div class="row">
                <div class="center">center</div>
                <div class="right" style="display:block">right</div>    
            </div>
            <div class="row">
                <div class="center">center</div>
                <div class="right" style="display:none">right</div>    
            </div>
            <div class="row">
                <div class="center">center</div>
                <div class="right" style="display:block">right</div>    
            </div>
            <div class="row">
                <div class="center">center</div>
                <div class="right" style="display:none">right</div>    
            </div>
        </div>
    </body>
</html>

现在,您遇到的问题是因为您只是尝试使用课程,就好像它是一个 id 。请记住,您对任何给定类所做的任何更改都会影响拥有它的每个元素,并且它将服从最后给出的命令。要完成所需的工作,仅使用类名,就必须逐一迭代该类名下的元素并分别进行修改:

$(function() {

    //rowCount is counting the number of rows in the document
    var rowCount = $(".row").length;
    var centerWidth1 =  $('#wrap').width();
    var centerWidth2 =  $('#wrap').width()-55;

    //this for loop iterates through all the rows, one by one, evaluating whether the "right" class element inside it is hidden or visible, and using your variables centerWidth1 and 2, sets the "center" width accordingly
    for (let i = 0; i <= rowCount; i++) {
        if ($(".row").eq(i).children().eq(1).is(":visible")) {
            $(".row").eq(i).children().eq(0).width(centerWidth2);
        } else {
            $(".row").eq(i).children().eq(0).width(centerWidth1);
        }
    }
});

此外,只需对 css 进行细微的观察:设置box-sizing: border-box可以避免界面上出现任何问题(如果添加任何边框)。而且没有必要,我什至不敢说在这些特定元素上设置inline-block对于您要尝试的操作是有问题的,因此您可以摆脱它。

.div {
    box-sizing: border-box;
}

#wrap {
    position: relative;
    margin: 20px auto;
    width: 80%;
    background-color: red;
}

.row {
    position: relative;
    height: 30px;
    margin-bottom: 10px;
}

.center {
    float: left;
    min-height: 30px;
    line-height: 30px;
    text-align: center;
    background-color: blue;
}

.right {
    float: left;
    width: 50px;
    min-height: 30px;
    line-height: 30px;
    text-align: center;
    margin-left: 5px;
    border:0;
    background-color: grey;
}

尝试一下,让我知道它是如何工作的。

编辑-使用flex:

//No Javascript or jQuery needed
.div {
    box-sizing: border-box;
}

#wrap {
    position: relative;
    margin: 20px auto;
    width: 80%;
    background-color: red;
}

/*Here in .row we set the flex display, so the elements inside are elastic*/
.row {
    position: relative;
    height: 30px;
    margin-bottom: 10px;
    display: flex; 
}

/*Here in .center we set it's default width to 100% to cover the whole container,
and by setting flex-shrink to 1, we're telling it to shrink by one the equivalent
amount of space that any extra items are causing the row to break into another line*/
.center {
    float: left;
    width: 100%;
    min-height: 30px;
    line-height: 30px;
    text-align: center;
    background-color: blue;
    flex-shrink: 1;
}

.right {
    float: left;
    width: 50px;
    min-height: 30px;
    line-height: 30px;
    text-align: center;
    margin-left: 5px;
    border:0;
    background-color: grey;
}
<!DOCTYPE html>
<html>
    <head>
        <title>Dynamic center</title>
    </head>
    <body>
        
<div id="wrap">
    <div class="row">
        <div class="center">center</div>
        <div class="right" style="display:block">right</div>    
    </div>
    <div class="row">
        <div class="center">center</div>
        <div class="right" style="display:none">right</div>    
    </div>
    <div class="row">
        <div class="center">center</div>
        <div class="right" style="display:block">right</div>    
    </div>
</div>
    </body>
</html>

同样,如果您实际上删除了.right元素以及将其保留在文档中并使用display: none,这也将起作用。运行代码片段以查看。