zoukankan      html  css  js  c++  java
  • 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的宽度,而后者不行。

    如有不正确或者需要补充的地方,欢迎指正!

  • 相关阅读:
    Handle类与线程
    android中ProgressBar和ListView
    RadioGroup、RadioButton、CheckBox、Toast用法
    Android开发中的menu菜单
    多个Activity相互调用和Intent
    ubuntu下安装h2数据库
    window下eclipse安装python插件
    centos7安装JDK1.8
    ubuntu设置root权限默认密码
    Linux给用户添加sudo权限
  • 原文地址:https://www.cnblogs.com/liuxianan/p/jquery_width_and_jquery_css_width.html
Copyright © 2011-2022 走看看