jQuery 1.8 盒模型:width()、css(“width”) 和 outerWidth()
jQuery 1.8 中一项很棒的新功能是对 `box-sizing: border-box` 的内置理解,该功能受所有现代浏览器支持。(抱歉,IE6 和 IE7 请退后一步;我说的是 _现代_ 浏览器。)
如果您在屏幕上显示一个带边框的元素并询问元素的宽度,他们自然会从边框的外边缘进行测量。但这不是 CSS 在其默认的 `content-box` 模式下的工作方式。通常情况下,CSS 宽度和高度仅包含边框和内边距内的“内容”。因此,设计师(和 jQuery)通常需要将宽度添加到左右内边距和边框,以获得元素的“自然”宽度。
使用 `box-sizing: border-box` 会将 CSS 对元素宽度的概念更改为包含内边距和边框尺寸,就像您自然测量它一样。jQuery 1.8 之前的版本 并未完全训练 `border-box` 的使用方法,但我们已经修复了此错误。
`width()` 方法的返回值未改变。正如文档一直以来的说明,它获取和/或设置元素的“内容”宽度,并且与元素使用的 CSS `box-sizing` 无关。但是,jQuery 1.8 现在需要在每次使用 `width()` 时检查 `box-sizing` 属性,以便它可以确定是否需要减去内边距和边框宽度。这可能会很昂贵 - 在 Chrome 上最多贵 100 倍!幸运的是,大多数代码不会频繁使用 `width()`,因此这并不明显,但是获取数十个元素宽度的代码可能会受到影响。
如果此性能损失影响了您的代码,则有一个非常简单的解决方法。只需使用 `css("width")` 而不是 `width()`,以便明确表示您要获取或设置元素的实际宽度(如 CSS 所指定)。这样就不需要 jQuery 查看 `box-sizing`。但是请记住,`css("width")` 作为获取器返回一个字符串,其末尾带有“px”,因此您需要使用类似 `parseFloat( $(element).css("width") )` 的东西来处理需要数值结果的情况。
当然,这里关于 `width()` 的所有内容也适用于 `height()`;使用 `css("height")` 来避免那里的性能损失。
使用 `outerWidth()` 作为设置器
在其他尺寸相关的新闻中,jQuery 的 `outerWidth()` 和 `outerHeight()` 方法已在 1.8 中更新,因此 它们可以用作设置器。(jQuery UI 自 UI 版本 1.8.4 以来一直支持它们作为设置器,但现在已内置到核心。)要将 `outerWidth()` 用作设置器,请传递一个表示外部宽度(CSS“内容”宽度,加上内边距和边框宽度)的数字参数。是的,这也会很好地处理 `box-sizing: border-box` 情况;它基本上与在该情况下设置 `css("width")` 相同。
我们收到了一些来自人们的报告,他们遇到了 jQuery 1.8 中 `outerWidth()` 的问题,因为它返回了 jQuery 对象而不是数值宽度。如果例如调用 `$(element).outerWidth(0)`,就会发生这种情况。在 jQuery 1.8 之前,这是一种无效的 API 使用方式,因为它在文档中被描述为接受一个 _布尔_ 参数。但是,它将无效参数视为布尔值并返回宽度。在 1.8 中,jQuery 使用值 0 来设置宽度,并且像大多数设置器一样,它返回 jQuery 对象。
我们正在更新 1.8 中所有更改的 API 文档,但目前您可以参考 jQuery 1.8 公告 中的更改日志,以查看发生了哪些更改。
感谢您的解释。outerWidth 是否也会受到性能影响?
@Tim,所有尺寸获取器实际上都得到了轻微的加速(取决于浏览器)。主要是在设置器情况下(对于 1.8,对于 outerWidth 和 innerWidth 来说是新的),速度变慢了。
总结
设置器
.outerWIdth()、.innerWidth():新的
.width():速度变慢
.css(“width”):未改变
获取器
.outerWIdth()、.innerWidth()、.width()、.css(“width”):未改变
哈哈,它也不起作用。看起来似乎无法提供任何 HTML 代码。请告诉我是否应该使用>/< 或其他符号。
<script type=”text/javascript” src=”https://code.jqueryjs.cn/jquery-1.8.0.js”></script>
<script type=”text/javascript”>
function check1() {
var e = $(“#span1”);
alert(“width():” + e.width() +
“\ncss(width):” + e.css(“width”) +
“\nstyle.width:” + e[0].style.width +
“\noffsetWidth-border/padding:” + (e[0].offsetWidth – 14) +
“\noffsetWidth:” + e[0].offsetWidth +
“\nheight():” + e.height() +
“\ncss(height):” + e.css(“height”) +
“\noffsetHeight-border/padding:” + (e[0].offsetHeight – 14) +
“\noffsetHeight:” + e[0].offsetHeight +
“\nstyle.height:” + e[0].style.height);
}
</script>
<style type=”text/css”>.css1 { border:2px solid blue;padding:5px;width:300px; }</style>
<span class=”css1″ id=”span1″ style=”background:red;height:300px;”>span1</span>
<input type=”button” id=”check1″ value=”check” onclick=”check1()” />
我简直不敢相信我之前一直没有使用 CSS box-sizing: border-box,它可以解决我至今为止数不胜数的工作量。我现在明白阅读“新增功能”的重要性,因为您通常会发现有用的东西。
“抱歉,IE6 和 IE7 请退后一步;我说的是现代浏览器。”
啊,我们已经走了一个完整的循环。在这里批评 IE 是错误的,因为实际上他们一开始就做对了。这个“现代”浏览器支持的功能实际上就像“怪癖”模式一样,旧的 IE 浏览器默认情况下就使用该模式。
http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug
现在,让我们回到我们正常计划的(并且通常应得的)IE 抨击。
关于您的最后一段,jQuery 现在已经足够流行,我们 http://stackoverflow.com/questions/12011925/pipe-and-then-documentation-vs-reality-in-jquery-1-8 在您有机会更新文档之前(或者甚至是在您更新文档的同时,根据评论)。
我认为这是一个相当大的成就。我有一种预感,许多用户不会期望对 then() 进行重大更改,而这仅仅是关于该更改的一系列问题中的第一个。希望新文档能指出这一点,这样我们只需链接到它们即可;)
感谢您一如既往的出色工作。
@jamie 虽然令人难过,但我们必须诚实地承认 IE 确实首先做了一些事情。边框框、CSS 渐变、透明度等等。
谢谢,我不再需要为我的 UI 对话框大小代码编写工作区了 :)
我确信我没有向 outerWidth 函数传递任何参数,但它也返回了 jQuery 对象!
@shuangbao.li – 我也遇到了同样的问题。每次调用 outerWidth() 时,都会返回 jQuery 对象。
返回对象而不是数字也是同样的问题 https://skitch.com/diiiimaaaa/exdak/up-t-shirt
如果你在所有情况下都遇到 outerWidth 和 outerHeight 返回 jQuery 对象的问题,请不要绝望。
包含 jQuery UI 版本 <= 1.8.21(2012 年 6 月 15 日发布)会导致 outerWidth 和 outerHeight 出现故障!只需升级 jQuery UI,所有问题都将解决。
http://jsfiddle.net/MaCxx/3/ – 故障 – jquery ui 1.8.21 http://jsfiddle.net/Mk82e/1/ – 已修复 – jquery ui 1.8.23
我不确定是错误还是预期功能(希望不是)。它不适用于标签。 示例在此处。
….
e = $(‘#svg1’)
w1 = e.width() // NaNpx
w2 = e.css(‘width’) // NaNpx
由于使用了“-moz-box-sizing”属性,流行的网页开发人员附加组件报告了 CSS 错误。我是一个完美主义者,这是我在网站上唯一的格式错误 - 我讨厌它。请以不同的方式解决这个问题,并删除这些垃圾。
我无法相信到目前为止我还没有使用 CSS box-sizing: border-box,它可以修复很多问题,以及到目前为止的许多执行周期。我现在确实看到了将“名人”纳入学习内容的意义,因为你通常会发现一些有用的因素。