为什么$('#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();
智能推荐

注意!

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



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

赞助商广告