JQuery获取元素宽度.width()与.css(‘width’)两个函数的区别

整理翻译自:http://blog.jquery.com/2012/08/16/jquery-1-8-box-sizing-width-csswidth-and-outerwidth/

大意是:

  在JQuery中

    .width返回的是:元素内容width + padding + border.

    .css('width')返回的是:元素内容width + 单位。

  其实这2个函数分别对应,两种理解元素宽度的方式。

    content-box : 元素的宽度就是内容的宽度,不包括 padding 和 border 宽度。

    border-box:   元素的宽度直观的就应该是:内容宽度 + padding宽度 + border 宽度。

  这是一段纠结的历史。

  在很久很久以前,IE6以前,浏览器是默认 border-box 模型的,后来(就CSS3出来之前)转而默认 content-box,到了CSS3,

二者和谐统一,方法就是CSS3推出一个属性 box-sizing,该属性值有2个:一个是 content-box,另一个就是 border-box。把怎么计算

元素宽度的问题抛给了设计师,算是给设计师们一个自由吧。详细见这

   下面是 JQuery 官网对 .width() 和 .css('width')  两个函数的“工作总结”和“适用情况”。

 

开始翻译:


One of the great new features in jQuery 1.8 is a built-in understanding of box-sizing: border-box which is supported by every modern browser. (Sorry, IE6 and IE7, please take one step back; I said modern browser.)

  JQuery 1.8的一个重要特性是内置的很容易理解的 box-sizing:border-box,每个现代浏览器(sorry,在作者眼里IE6和IE7不算现代浏览器)都支持它。

 

If you showed people an element with a border on the screen and asked them the width of that element, they would naturally measure from the outside edges of the border. Yet that’s not the way CSS works in its default content-box mode. Normally, CSS width and height only include the “content” inside the border and padding. As a result, designers (and jQuery) often need to add the width to the right/left padding and border to get the “natural” width of the element.

  如果你在屏幕上向别人展示一个带有边框的元素,问他们这个元素的宽度是多少,他们会很自然的从边框的外边缘算起(即把边框宽度也计算在内)。然而默认content-box模型的CSS却不是这么工作的。一般来说,CSS中的 width 和 height 只是计算位于border和padding内的正文内容(content)的宽度和高度。这么做的结果就是Web工程师(和JQuery)经常需要手动将左右 padding 及 border 的 width 和元素的“自然宽度”相加。

 

Using box-sizing: border-box changes the CSS notion of the width of an element to include both the padding and the border dimensions, just the way you’d naturally measure it. jQuery versions before 1.8 were not fully trained in the ways of the border-box, but we’ve fixed this bug.

  使用 box-sizing: border-box 属性值改变一个元素的CSS默认的“宽度”来使之包含padding和border宽度,这正是你测量它的宽度很自然的做法。JQuery1.8之前的版本并没有充分支持 border-box 模型,但是现在我们已经修复这个Bug。

 

One thing that hasn’t changed is the return value of the .width() method. As it’s always been documented, it gets and/or sets the “content” width of an element, and that is regardless of the CSS box-sizing being used by the element. However, jQuery 1.8 now needs to check the box-sizing property whenever you use .width() so that it can decide whether it needs to subtract out the padding and border width. That can be expensive—up to 100 times more expensive on Chrome! Fortunately, most code doesn’t use .width() enough times for this to be noticeable, but code that gets the width of dozens of elements at once could be impacted.

  有个东西我们没有改动,那就是 .width() 的返回值。就像文档里面通常描述的那样,尽管可能已经在元素中设置了CSS的 box-sizing 属性值,它还是会get/set元素的“content”宽度。但是,JQuery 1.8 现在无论你什么时候使用 .width()函数,它都需要检测 box-sizing 属性,所以它可以决定是否需要减掉 padding 和 border 的宽度。这个操作代价不菲,在Chrome上更是昂贵的100都不止!幸运的是,大多数的代码使用的次数都不足以察觉到这个代价的后果,但是当出现同时获取几十个元素的宽度时,这种代价可能会被察觉到。

 

There is a very easy way to avoid this performance penalty if it does impact your code. Simply use .css("width") instead of.width() to make it clear you want to get or set the actual width of the element as specified by the CSS. That doesn’t require jQuery to look at box-sizing. Remember, however, that .css("width") as a getter returns a string with “px” at the end, so you’ll want to use something like parseFloat( $(element).css("width") ) for situations where the result must be numeric.

And of course, everything mentioned here about .width() also applies to .height() as well; use .css("height") to skirt the performance penalty there.

  如果它确实影响到了你的代码,倒是有一种很简单的方法可以避免这种性能“惩罚(不懂如何翻译鸟,反正就是牺牲性能的意思)”。简单来说,使用 .css("width") 替换掉 .width() 可以使你get/set元素的那种由CSS规定的实际宽度。这样就不再需要JQuery去费劲儿的找box-sizing属性 。但是,要记住, .css("width")  返回值的时候会返回带单位“px”的宽度值,所以你必须在需要返回数字的情况下,使用函数 parseFloat( $(element).css("width") ) 。

  当然了,这里提到的关于 .width() 的东西都适用于 .height(),同样, .css("height")什么的也是如此。

 


翻译完了。

  

  最后,额外补充一下,文中说的 box-sizing虽然是各大现代浏览器们(Firefox,Safari,Chrome,Opera)和IE8都支持的CSS3新属性,但是还需要加上各自的前缀。

  Mozilla需要加上         -moz-

  Webkit内核需要加上   -webkit-

  Presto内核要加上      -o-

  IE8要加上                -ms-

  例子如下(无耻的盗用了这个博客的例子和图):

 <div class="imgBox" id="contentBox"><img src="/images/header.jpeg" alt="" /></div>
   <div class="imgBox" id="borderBox"><img src="/images/header.jpeg" alt="" /></div>
.imgBox img{
     width: 140px;
     height: 140px;
     padding: 20px;
     border: 20px solid orange;
     margin: 10px;
  }
  #contentBox img{
     -moz-box-sizing: content-box;
     -webkit-box-sizing: content-box;
     -o-box-sizing: content-box;
     -ms-box-sizing: content-box;
     box-sizing: content-box; 
  }

  #borderBox img{
     -moz-box-sizing: border-box;
     -webkit-box-sizing: border-box;
     -o-box-sizing: border-box;
     -ms-box-sizing: border-box;
     box-sizing: border-box;
  }

 

水平所限,有问题还望多多指正,不敢误人子弟。

 

 

 

 

 

 .

posted @ 2014-02-25 19:21  HolyGrail  阅读(14730)  评论(1编辑  收藏  举报
设计良好的程序将用户的注意力视为有限的宝贵资源,只有在必要时才要求使用。 ——《Unix编程艺术》