jQuery.width()和jQuery.css('width')的区别
问题描述
使用jQuery修改一个div的宽度时,发现$($0).width('10rem')
总是修改成不正确的值,然后使用$($0).css('width', '10rem')
时却能正确,简单得查阅了下jQuery文档,发现文档里面对$.fn.width的描述是:
val为空时是取得第一个匹配元素当前计算的宽度值(px),val不为空时是设置宽度,可以是字符串或者数字,还可以是一个函数。
刚开始还以为是$.fn.width只支持px,对rem支持不好,后来跟踪了一下源码发现想法错了。
调试
我使用的是jquery-v1.11.1.js。
Chrome控制台下输入$.fn.width定位到10206行:
在这个地方打一个断点,输入$($0).width('10rem')
开始跟踪,进入了jQuery.style( elem, type, value, extra )
,继续往下,发现经过如下代码时val发生了变化,变成了一个错误的值,10rem
变成了34rem
:
看来就是这个hook引起的,重新来一次,按下F11进入hook看一下,进入了$.cssHooks.width.set
:
看到了一个很关键的方法augmentWidthOrHeight
(扩大宽度或者高度),很显然问题出在这里,没有特别仔细看,大概逻辑是,如果borderBox,那么val减去padding和border的值,如果不是,那么加上:
测试的$0的宽高度如下,因为没有border,所以这里计算出来就是paddingLeft+paddingRight
,也就是-24:
再看setPositiveNumber方法,里面强行把10rem
中的10跟上面计算出来单位为px
的-24相减!难怪会出错:
return 10(单位是rem) - (-24(单位是px)) + 'rem';
说白了就是jQuery这个hook只能处理单位是px的,单位是其它的就有问题了。那么回到最开始,$.fn.width
和$.fn.css('width')
有啥区别呢?
可以发现,$.fn.width
最终调用的是jQuery.style( elem, type, value, extra )
,$.fn.css
调用的是jQuery.style( elem, name, value )
,唯一的差别是前者多了一个extra。
总结和补充
- $.fn.width会根据是否是borderBox来计算新的宽度,如果是borderBox,会额外加上padding和border的宽度,计算时只是按照px来,用rem做单位会出错;
- 另外,
$.fn.width
返回的是不带单位的number类型,$.fn.css('width')
返回的是带单位的字符串; - 通过源码还可以发现,$.fn.width可以计算window和document的宽度,而后者不行。
如有不正确或者需要补充的地方,欢迎指正!

github:https://github.com/sxei
博客园:http://www.cnblogs.com/liuxianan
copyright ©2012-2020 小茗同学
【转载文章务必保留出处和署名,谢谢!】
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?