使用jQuery设置元素高度给出不正确的高度

时间:2017-08-23 21:34:23

标签: jquery html css

我有一个元素列表(我称之为卡片),每个元素的宽度为33%,以填充页面。它们内部是标题和细节,我想通过单击复选框显示所有这些细节。细节的长度在所有卡片之间是可变的,因此当用户点击以显示细节时,我试图获得每张卡片细节的高度,将它们设置为相同,然后在所有卡片上显示细节。

我正确设置了高度但是一旦调用slideDown(),它们的高度就会高于我设定的高度。我终于弄清楚它与data-set-labeldata-set-datainline-block并且宽度为50%有关。如果删除它,slideDown()会显示正确的高度。几乎好像slideDown()没有考虑到内联块元素在同一条线上,但这看起来并不正确...

出了什么问题?



$(document).ready(function() {
  $("#ShowDetailsCheckBox").change(function() {
    if ($(this).is(":checked")) {
      setContentDataHeights();
      $(".cards-card-detail").slideDown();
    } else {
      $(".cards-card-detail").slideUp();
    }
  });
});

function setContentDataHeights() {
  var maxContentDataHeight = 0;

  $(".cards-card-detail").each(function() {
    if ($(this).height() > maxContentDataHeight)
      maxContentDataHeight = $(this).height();
  });

  if (maxContentDataHeight > 0) {
    $(".cards-card-detail").each(function() {
      //$(this).css("height", maxContentDataHeight.toString() + "px");
      $(this).height(maxContentDataHeight);
    });
  }
}

* {
  box-sizing: border-box;
}

.cards {
  font-size: 0;
}

.cards-card {
  font-size: 12pt;
  display: inline-block;
  width: 33%;
  vertical-align: top;
  border: 1px solid red;
}

.cards-card:nth-child(2n) {
  width: 34%;
  border: 1px solid green;
}

.cards-card-header {
  height: 100px;
}

.cards-card-detail {
  padding: 10px;
  border-top: 1px solid red;
  display: none;
}

.data-set-wrapper {
  width: 100%;
  font-size: 0;
}

.data-set-label {
  font-size: 12px;
  border: 1px solid red;
  width: 50%;
  display: inline-block;
}

.data-set-data {
  font-size: 12px;
  border: 1px solid red;
  width: 50%;
  display: inline-block;
}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<input type="checkbox" id="ShowDetailsCheckBox" />Show details
<div class="cards">
  <div class="cards-card">
    <div class="cards-card-header">
      Here is some header information
    </div>
    <div class="cards-card-detail">
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
    </div>
  </div>
  <div class="cards-card">
    <div class="cards-card-header">
      Here is some header information
    </div>
    <div class="cards-card-detail">
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
    </div>
  </div>
  <div class="cards-card">
    <div class="cards-card-header">
      Here is some header information
    </div>
    <div class="cards-card-detail">
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
    </div>
  </div>
</div>
&#13;
&#13;
&#13;

View on JSFiddle

1 个答案:

答案 0 :(得分:0)

那非常时髦。

理论:

.cards-card-detail元素具有display:none时,其宽度未定义。 .data-set-label个元素有width:50%但是,与他们的父母一起#{1}} widths undefined,它们的宽度以一种奇怪的方式计算,导致内部文本换行,高度被抛弃。

一些测试:

在下面的测试中,.data-set-label的宽度计算为&#34; 50像素&#34;,即使它被定义为&#34; 50%&#34;。但是当.cards-card-detaildisplay:block时,会返回更准确的宽度。

&#13;
&#13;
$(function() {
  console.log("display:none - " + $('.data-set-label').width());
  $('.cards-card-detail').show()
  console.log("display:block - " + $('.data-set-label').width());
});
&#13;
* {
  box-sizing: border-box;
}

.cards {
  font-size: 0;
}

.cards-card {
  font-size: 12pt;
  display: inline-block;
  width: 33%;
  vertical-align: top;
  border: 1px solid red;
}

.cards-card:nth-child(2n) {
  width: 34%;
  border: 1px solid green;
}

.cards-card-header {
  height: 100px;
}

.cards-card-detail {
  padding: 10px;
  border-top: 1px solid red;
  display: none;
}

.data-set-wrapper {
  font-size: 0;
}

.data-set-label {
  font-size: 12px;
  border: 1px solid red;
  width: 50%;
  display: inline-block;
}

.data-set-data {
  font-size: 12px;
  border: 1px solid red;
  width: 50%;
  display: inline-block;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

<div class="cards">
  <div class="cards-card">
    <div class="cards-card-header">
      Here is some header information
    </div>
    <div class="cards-card-detail">
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
    </div>
  </div>
</div>
&#13;
&#13;
&#13;

.data-set-label的宽度明确设置为&#34; 50px&#34;使文本换行并增加.cards-card-detail的高度,看似相同&#34;错误&#34;高度如你的例子(巧合?)。

&#13;
&#13;
* {
  box-sizing: border-box;
}

.cards {
  font-size: 0;
}

.cards-card {
  font-size: 12pt;
  display: inline-block;
  width: 33%;
  vertical-align: top;
  border: 1px solid red;
}

.cards-card:nth-child(2n) {
  width: 34%;
  border: 1px solid green;
}

.cards-card-header {
  height: 100px;
}

.cards-card-detail {
  padding: 10px;
  border-top: 1px solid red;
}

.data-set-wrapper {
  font-size: 0;
}

.data-set-label {
  font-size: 12px;
  border: 1px solid red;
  width: 50px;
  display: inline-block;
}

.data-set-data {
  font-size: 12px;
  border: 1px solid red;
  width: 50px;
  display: inline-block;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

<div class="cards">
  <div class="cards-card">
    <div class="cards-card-header">
      Here is some header information
    </div>
    <div class="cards-card-detail">
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
    </div>
  </div>
</div>
&#13;
&#13;
&#13;

解决方案:

我通过定义.cards-card-detail的宽度在&#34; 100%&#34;取得了一些成功。在希望孩子们的#39; &#34; 50%&#34;然后将正确设置宽度。

&#13;
&#13;
$(function() {

  $("#ShowDetailsCheckBox").change(function() {
    if ($(this).is(":checked")) {
      setContentDataHeights();
      $(".cards-card-detail").slideDown();
    } else {
      $(".cards-card-detail").slideUp();
    }
  });

});

function setContentDataHeights() {

  var maxContentDataHeight = 0;

  $(".cards-card-detail").each(function() {
    if ($(this).height() > maxContentDataHeight)
      maxContentDataHeight = $(this).height();
  });

  if (maxContentDataHeight > 0) {
    $(".cards-card-detail").height(maxContentDataHeight);
  }

}
&#13;
* {
  box-sizing: border-box;
}

.cards {
  font-size: 0;
}

.cards-card {
  font-size: 12pt;
  display: inline-block;
  width: 33%;
  vertical-align: top;
  border: 1px solid red;
}

.cards-card:nth-child(2n) {
  width: 34%;
  border: 1px solid green;
}

.cards-card-header {
  height: 100px;
}

.cards-card-detail {
  padding: 10px;
  border-top: 1px solid red;
  display: none;
  width: 100%;
}

.data-set-wrapper {
  font-size: 0;
}

.data-set-label {
  font-size: 12px;
  border: 1px solid red;
  width: 50%;
  display: inline-block;
}

.data-set-data {
  font-size: 12px;
  border: 1px solid red;
  width: 50%;
  display: inline-block;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<input type="checkbox" id="ShowDetailsCheckBox" />Show details
<div class="cards">
  <div class="cards-card">
    <div class="cards-card-header">
      Here is some header information
    </div>
    <div class="cards-card-detail">
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
    </div>
  </div>
  <div class="cards-card">
    <div class="cards-card-header">
      Here is some header information
    </div>
    <div class="cards-card-detail">
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
    </div>
  </div>
  <div class="cards-card">
    <div class="cards-card-header">
      Here is some header information
    </div>
    <div class="cards-card-detail">
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
    </div>
  </div>
</div>
&#13;
&#13;
&#13;

我对其他解释感到好奇。

修改

我明白你的意思了:上面的解决办法并不是一贯的 这是一种替代技术:

.cards设置为opacity:0,直到.card-card-detail的高度设置为止。然后揭开卡片。

&#13;
&#13;
$(document).ready(function() {

  setContentDataHeights();
  $('.cards-card-detail').hide();
  $('.cards').addClass('show');

  $("#ShowDetailsCheckBox").change(function() {
    if ($(this).is(":checked")) {
      $(".cards-card-detail").slideDown();
    } else {
      $(".cards-card-detail").slideUp();
    }
  });
});

function setContentDataHeights() {
  var maxContentDataHeight = 0;

  $(".cards-card-detail").each(function() {
    if ($(this).height() > maxContentDataHeight)
      maxContentDataHeight = $(this).height();
  });

  if (maxContentDataHeight > 0) {
    $(".cards-card-detail").height(maxContentDataHeight);
  }
}
&#13;
* {
  box-sizing: border-box;
}

.cards {
  font-size: 0;
  opacity: 0;
  transition: opacity .25s;
}

.cards.show {
  opacity: 1;
}

.cards-card {
  font-size: 12pt;
  display: inline-block;
  width: 33%;
  vertical-align: top;
  border: 1px solid red;
}

.cards-card:nth-child(2n) {
  width: 34%;
  border: 1px solid green;
}

.cards-card-header {
  height: 100px;
}

.cards-card-detail {
  padding: 10px;
  border-top: 1px solid red;
}

.data-set-wrapper {
  font-size: 0;
}

.data-set-label {
  font-size: 12px;
  border: 1px solid red;
  width: 50%;
  display: inline-block;
  vertical-align: top;
}

.data-set-data {
  font-size: 12px;
  border: 1px solid red;
  width: 50%;
  display: inline-block;
  vertical-align: top;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="checkbox" id="ShowDetailsCheckBox" />Show details
<div class="cards">
  <div class="cards-card">
    <div class="cards-card-header">
      Here is some header information
    </div>
    <div class="cards-card-detail">
      <div class="data-set-wrapper">
        <label class="data-set-label">label label label label label label </label>
        <div class="data-set-data">
          some data
        </div>
      </div>
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
    </div>
  </div>
  <div class="cards-card">
    <div class="cards-card-header">
      Here is some header information
    </div>
    <div class="cards-card-detail">
      <div class="data-set-wrapper">
        <label class="data-set-label">label label label label label label label label label label </label>
        <div class="data-set-data">
          some data
        </div>
      </div>
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
    </div>
  </div>
  <div class="cards-card">
    <div class="cards-card-header">
      Here is some header information
    </div>
    <div class="cards-card-detail">
      <div class="data-set-wrapper">
        <label class="data-set-label">Label</label>
        <div class="data-set-data">
          some data
        </div>
      </div>
    </div>
  </div>
</div>
&#13;
&#13;
&#13;