為什么$('#foo')。css('width',$('#foo')。css('width'))會改變寬度?

[英]Why does $('#foo').css('width', $('#foo').css('width')) change the width?


One would think that after the following bit of jQuery, the width of the div selected by #foo would not change at all; after all, we are setting this width to the value it supposedly already has:

有人會認為,在jQuery的下一部分之后,#foo選擇的div的寬度根本不會改變;畢竟,我們將此寬度設置為它應該具有的值:

var original_width = $('#foo').css('width');
$('#foo').css('width', original_width);

In fact, this reasonable guess appears to be wrong, as shown in this page. I give the code below. The important thing to note is that the four main sections, corresponding to the four .level-0 divs, all have the same structure and content. The second and fourth of them (which have the jqbug class) have their width "re-set" (with a bit of JS, as described above) to the value it supposedly already has. For the second one case, the width is actually changed by this operation; for the fourth case, the width remains unchanged, as expected. The only difference between the definitions of the second and fourth cases is that the former has border-box for its box-sizing parameter.

事實上,這個合理的猜測似乎是錯誤的,如本頁所示。我給出下面的代碼。需要注意的重要一點是,對應於四個.level-0 div的四個主要部分都具有相同的結構和內容。它們中的第二個和第四個(具有jqbug類)將它們的寬度“重新設置”(帶有一點JS,如上所述)到它應該已經具有的值。對於第二種情況,寬度實際上是通過此操作改變的;對於第四種情況,寬度保持不變,如預期的那樣。第二個和第四個案例的定義之間的唯一區別是前者的盒子大小參數有邊框。

<div class="level-0 border-box">
    <div id="i1" class="level-1">
      <p>Lorem ipsum dolor sit amet</p>
    </div>
</div>

<div class="level-0 border-box">
    <div class="level-1 jqbug">
      <p>Lorem ipsum dolor sit amet</p>
    </div>
</div>

<div class="level-0">
    <div id="i1" class="level-1">
      <p>Lorem ipsum dolor sit amet</p>
    </div>
</div>

<div class="level-0">
    <div class="level-1 jqbug">
      <p>Lorem ipsum dolor sit amet</p>
    </div>
</div>

<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js">
</script>


  (function ($) {
    $('.jqbug').each(function () {
      $(this).css('width', $(this).css('width'));
    });

  }(jQuery));


*{
  outline:3px solid green;
}

.border-box, .border-box *{
  -webkit-box-sizing:border-box;
     -moz-box-sizing:border-box;
          box-sizing:border-box;
}

.level-0{
  position:relative;
  margin:10px auto;
  width:300px;
  height:100px;
  font-family:consolas,monaco,courier,monospace;
}
.level-1{
  position:absolute;
  padding:10px 20px;
  background-color:#0aa;
  font-size:15px;
}

In this jsFiddle, which uses exactly the same code as shown above, all the divs end up with the same width. On the one hand, this is good: the results have the appearance one would expect. On the other hand, the fact that jsFiddle's result is not representative of what the browser produces directly is just as puzzling as jQuery's behavior.

在這個jsFiddle中,它使用與上面所示完全相同的代碼,所有div最終都具有相同的寬度。一方面,這很好:結果具有人們所期望的外觀。另一方面,jsFiddle的結果並不代表瀏覽器直接生成的事實就像jQuery的行為一樣令人費解。

My questions are:

我的問題是:

  1. Is this a bug in jQuery, or is this puzzling behavior somehow in agreement with the CSS spec?

    這是jQuery中的一個錯誤,還是這個令人費解的行為在某種程度上與CSS規范一致?

  2. What does one need to do to get the result produced by jsFiddle to look like that produced by the browser?

    需要做些什么才能使jsFiddle生成的結果看起來像瀏覽器生成的結果?

EDIT: I modified the JS (in both the page linked above and the jsFiddle, as well as in this post) to match that given in Marco Biscaro's answer; this made no difference to the appearance of the page as displayed directly by the browser, but it did affect the appearance of the jsFiddle's result. Now the latter shows no difference in the widths of the various divs. This result still differs from that produced directly by the browser, so the situation is not much better than it was before: we still have that jQuery produces surprising results, and jsFiddle produces results that do not match the browser's results.

編輯:我修改了JS(在上面鏈接的頁面和jsFiddle,以及在這篇文章中),以匹配Marco Biscaro的回答;這對瀏覽器直接顯示的頁面外觀沒有影響,但它確實影響了jsFiddle結果的外觀。現在后者顯示各種div的寬度沒有差異。這個結果仍然與瀏覽器直接產生的結果不同,因此情況並沒有比以前好多了:我們仍然認為jQuery會產生令人驚訝的結果,並且jsFiddle會產生與瀏覽器結果不匹配的結果。

3 个解决方案

#1


1  

You have two different divs with the same class. When you do:

你有兩個不同的div具有相同的類。當你這樣做時:

$('.jqbug').css('width')

The width of one of the divs is returned (I don't know exactly how jQuery determines which of two). In your hosted page, the value returned is 234px while in jsFiddle the value is 274px (again, I don't know exactly why). This is why the behaviour is different between the two pages.

返回其中一個div的寬度(我不知道jQuery如何確定兩個中的哪一個)。在您的托管頁面中,返回的值是234px,而在jsFiddle中,值是274px(再次,我不知道具體原因)。這就是兩個頁面之間行為不同的原因。

This returned value is applied as width of both divs, but because one div has the box-sizing: border-box and the other hasn't, one div gets bigger than the other.

此返回值作為兩個div的寬度應用,但因為一個div具有box-sizing:border-box而另一個沒有,所以一個div比另一個div大。

jQuery won't change the width of any div, as expected, if you set the width as the original width and use $(document).ready (http://bugs.jquery.com/ticket/14084):

如果將寬度設置為原始寬度並使用$(document).ready(http://bugs.jquery.com/ticket/14084),jQuery將不會像預期的那樣更改任何div的寬度。

$(document).ready(function () {
    $('.jqbug').each(function () {
        $(this).css('width', $(this).css('width'));
    });
});

#2


0  

This problem is caused by the fact that the first div has the css class border-box on the higher level element which has a different width vs the second element where the parent element does not have border-box set on it.

這個問題是由於第一個div在較高級別元素上具有css類border-box而與第二個元素具有不同寬度的事實引起的,其中父元素沒有設置border-box。

border-box has the box sizing model set on it. This means it takes the width+padding.

border-box上設置了框大小模型。這意味着它需要寬度+填充。

This causes the inline width set by jquery to be overriden.

這會導致jquery設置的內聯寬度被覆蓋。

#3


0  

Just take the outerWidth, it will calculate the actual width including padding and border

只需取外邊寬度,它將計算實際寬度,包括填充和邊框

var original_width = $('#foo').outerWidth();
关注微信公众号

注意!

本站翻译的文章,版权归属于本站,未经许可禁止转摘,转摘请注明本文地址:https://www.itdaan.com/blog/2013/12/21/7deef4cb14db83eaaca0a9d372609cf2.html



 
粤ICP备14056181号  © 2014-2020 ITdaan.com