相关文章推荐
玩命的奔马  ·  Edge IE ...·  6 天前    · 
乖乖的四季豆  ·  about Functions ...·  1 年前    · 
曾经爱过的西装  ·  目标检测脚本 | ...·  1 年前    · 
聪明的勺子  ·  FormsAuthentication.Si ...·  1 年前    · 
忐忑的土豆  ·  vue router 4 ...·  1 年前    · 
本文基于jquery1.7.2,主要从三个方面逐层深入分析jquery CSS样式相关部分源码,分别为1、方法使用(.css的常见使用方法) 2、源码概览(主要api以及对应api的作用) 3、源码解析(对源码概览里提到的api进行较为深入的解析)...

jquery版本:1.7.2

根据实际需要,对CSS部分无关代码进行适当删除,如有疑问,可参见jquery源码: http://code.jquery.com/jquery-1.7.2.js

因实际工作中暂时没有用到jquery,故对jquery了解很粗浅,文章可能有错漏之处,敬请见谅并指出

本文参考借鉴了nuysoft 的jquery源码分析系列,挺不错的系列文章,推荐下:

http://www.cnblogs.com/nuysoft/archive/2011/11/14/2248023.html

jquery里节点样式 读取 以及 设置 都是通过.css()这个方法来实现的,本章通过以下三个部分简单探究下jquery里这部分代码的实现

一、方法使用

常见的有 四种用法 ,包括 一种读取样式 三种设置样式 :(详细可参见: http://api.jquery.com/css/

(1)读取样式:

.css(propertyName)  //用法1

(2)设置演示:

.css(propertyName, value)  //用法2

.css(propertyName, function(index, oldValue))  //用法3

.css(map)  //用法4

首先看下面几个例子:

<div id="header"></div>
<ul id="list">
    <li></li> <li></li> <li></li>
$('#header').css('height');  //读取样式值
$('#header').css('height', '10px');  //设置样式值
$('#header').css({height:'20px', 'width':'20px'});  //通过map方式设置多个属性
$('#list li').css('height', function(index, oldValue){ //通过传入function来设置样式,常用于集合操作
                                //index:为对应集合元素的索引,从0开始;而oldValue:元素原先样式
    return index*10+'px';  //返回值:节点最终设置的样式值

二、源码概览

主要代码:

  • jQuery.fn.css  //对外接口,样式读取、设置都通过它完成
  • jQuery.access  //jQuery.fn.css内部调用的,完成样式的读取、设置
  • jQuery.css  //读取节点样式(实际渲染后)
  • jQuery.style  //读取节点样式(内联样式)、设置节点样式
  • curCSS  //浏览器内置获取节点样式方法,为(1)支持标准的浏览器:getComputedStyle (2)IE系列:currentStyle
  • 其他相关:

  • jQuery.cssHooks  //钩子函数,某些样式,如'height'、'width'等用到
  • jQuery.support  //浏览器对某些特性的支持,详情见下文
  • jQuery.swap  //节点隐藏等情况下,height、width等获取值不准,此时需利用此方法来获得准确值,详情见下文
  • jQuery.cssProps  //某些属性,在浏览器里有各自的别名,如float:IE里为styleFloat,遵守标准的浏览器里为cssFoat,详情见下文
  • jQuery.cssNumber  //某些属性,如z-index,为数值类型,不需要单位,详情见下文
  • 相关正则:

        详情见下文

    三、源码解析

    主要代码:

  • jQuery.fn.css  //对外接口,样式读取、设置都通过它完成
  • * @description 真正对外提供的接口,包括 读取/设置 dom节点样式 * @param * @example 方式1:$('#header').css('height') ==> jQuery.css * 方式2:$('#header').css('height', '20px'),采用这种方式设置,只会对第一个元素进行样式设置 ==> jQuery.style 方式3:$('ul#list li.item').css(attr, function(index,oldValue){}),最终在内部转换成 jQuery.style(attr, newValue)的形式 ==> jQuery.style 方式4:$('#header').css({'height':'10px', 'width':'20px'}),最终在内部转换成$(node).style(attr, value)形式 ==> jQuery.style jQuery.fn.css = function( name, value ) { //此处需要比较需要关心的是 function( elem, name, value ) 这个匿名方法 //在jQuery.access经过各种判断检测后,最终就是调用这个匿名方法,遍历this,进行样式读取、设置 //elem:设置/读取样式的节点 //name:样式名 //value:样式值 return jQuery.access( this, function( elem, name, value ) { return value !== undefined ? jQuery.style( elem, name, value ) : //设置样式,方式2、3、4的最终归宿,jQuery.style源码解析见下文 jQuery.css( elem, name ); //读取样式,方法1的最终归宿,jQuery.css源码解析见下文 }, name, value, arguments.length > 1 ); //arguments.length > 1,即value!=undefined,为设置样式 //此处判断目的为:如设置样式,最后需返回elem,以实现链式调用,如$(node).css('height','10px').css('width','20px') //当采用$(node).css(map)方式设置,arguments.length == 1,按照此处逻辑判断,为读取样式 //jQuery.access对这种情况进行了特殊处理,同样返回elem,个人觉得这里写法有点诡异 //jQuery.access 定义如下,源码解析见下文;此处只是方便参照把定义拷贝了过来,源码里是没有下面这一句的 //jQuery.access = function( elems, fn, key, value, chainable, emptyGet, pass ){} //在css样式设置这块,emptyGet、pass两个参数没用到,请直接忽视, * @description 多功能函数,来自地狱的代码 * 多处用到,包括 jQuery.fn.css, jQuery.fn.attr, jQuery.fn.prop,此处只分析CSS相关部分 * @param {DOMObject} elems 读取/设置 样式的dom元素 * @param {Function} fn 读取/设置 样式对应的方法(1)读取:jQuery.css(elem) (2)设置jQuery.style(elem,key,value) * @param {String} key 读取/设置 样式对应的属性,如.css('height'),则key === 'height' * @param {Boolean} chainable 是否需要返回jQuery对象实现链式调用 * @emptyGet CSS样式部分貌似木有用到,暂忽略 * @pass CSS样式部分貌似木有用到,暂忽略 jQuery.access = function( elems, fn, key, value, chainable, emptyGet, pass ) { var exec, bulk = key == null, //key==null,表示key为null或者undefined i = 0, //多么糟糕的变量啊!!又做index索引,又做对象的键值 length = elems.length; // Sets many values if ( key && typeof key === "object" ) { //设置样式,对应jQuery.fn.css 方式4,如:$('#header').css({'height':'10px', 'width':'20px'}) //通过遍历哈希表方式,逐个设置节点样式 //此时key形式为:{'height':'10px', 'width':'20px'},key这变量名相当有迷惑性 for ( i in key ) { jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); //逐个设置样式,此处value==undefined chainable = 1; //chainable = 1 ,表示此处设置样式 // Sets one value } else if ( value !== undefined ) { //设置样式,如方式3:$('ul#list li.item').css('height', function(index,node){}) //方式2:$('#header').css('height', '20px') // Optionally, function values get executed if exec is true exec = pass === undefined && jQuery.isFunction( value ); //exec == true,则表示采用.css( property, function(index, oldValue) )方式设置样式 if ( bulk ) { //@todo:目前还没想到神马情况下会走到这个分支里,有可能CSS样式设置里不会出现,待进一步考察 // Bulk operations only iterate when executing function values if ( exec ) { exec = fn; fn = function( elem, key, value ) { return exec.call( jQuery( elem ), value ); // Otherwise they run against the entire set } else { fn.call( elems, value ); fn = null; if ( fn ) { for (; i < length; i++ ) { //遍历集合里的元素 //value.call( elems[i], i, fn( elems[i], key ) )返回节点设置之前的的样式 //value ==> function(index, oldValue),i对应index, fn( elems[i], key )对应oldValue, fn为 jQuery.css //exec值参见上文 fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); chainable = 1; return chainable ? //chainable == 1,表示设置样式,返回设置样式的元素,实现链式调用 // 设置样式,返回元素 elems : // 获取样式 bulk ? //bulk值参见上文 fn.call( elems ) : length ? fn( elems[0], key ) : emptyGet; //此时fn对应 jQuery.css //当elems为集合元素时,返回集合里第一个元素key对应的样式值
                                     //此处的返回值为access的返回值,也即.css(propertyName)的返回值
  • jQuery.css  //读取节点样式(实际渲染后)
  • * @description 读取 dom 实际渲染的样式值 * @param {DOMObject} elem 获取样式的dom节点 * @param {String} name 样式名 * @param extra css: function( elem, name, extra ) { var ret, hooks; // Make sure that we're working with the right name name = jQuery.camelCase( name ); //转成驼峰形式,如margin-left --> marginLeft hooks = jQuery.cssHooks[ name ]; //某些特定的属性有对应的get、set方法,如'height'、'width'、'opacity'等 name = jQuery.cssProps[ name ] || name; //对某些特殊属性,如float进行修正 // cssFloat needs a special treatment if ( name === "cssFloat" ) { //兼容标准的浏览器如chrome,用$(node).css('float')或$(node).css('cssFloat') name = "float"; // If a hook was provided get the computed value from there //如果有对应的hook对象,且该对象有get方法,则调用hooks[name].get 来获取样式值 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { return ret; // Otherwise, if a way to get the computed value exists, use that } else if ( curCSS ) { //否则,通过curCSS方法来获取实际渲染后的样式值,curCSS定义见curCSS部分说明 return curCSS( elem, name );
  • jQuery.style  //读取节点样式(内联样式)、设置节点样式
  •     // Get and set the style property on a DOM Node
         * @description 读取/设置 dom 节点样式
         * @param {DOMObject} elem dom节点
         * @param {String} name 属性值
         * @param {String|Number} value 样式值
         * @note 当获取样式值时,返回的是内联样式值,而非浏览器实际渲染后的值
        style: function( elem, name, value, extra ) {
            // Don't set styles on text and comment nodes
            //elem.nodeType ==> 3:文本,8:注释,此处过滤文本、注释节点
            //elem为document,则document.style == undefined,过滤无法设置属性的节点
            if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
                return;
            // Make sure that we're working with the right name
            var ret, type, origName = jQuery.camelCase( name ),    //返回驼峰命名形式的属性名
                style = elem.style, hooks = jQuery.cssHooks[ origName ];
            name = jQuery.cssProps[ origName ] || origName;    //float返回cssFloat或styleFloat(目前就只对这个属性进行特殊处理)
            // Check if we're setting a value
            if ( value !== undefined ) {
                type = typeof value;
                // convert relative number strings (+= or -=) to relative numbers. #7345
                //采用相对值进行设置,如$(node).css('height','+=10px')
                //ret = rrelNum.exec( value ),如采用相对值进行设置,则:
                //ret[1]:+/-
                //ret[2]:相对值的大小
                if ( type === "string" && (ret = rrelNum.exec( value )) ) {
                    value = ( +( ret[1] + 1) * +ret[2] ) + parseFloat( jQuery.css( elem, name ) );    //将相对值与原来的属性值进行运算,获得实际设置的值
                    // Fixes bug #9237
                    type = "number";
                // Make sure that NaN and null values aren't set. See: #7116
                //如果设置的值为 null 或者 NaN,则不设置,直接返回
                if ( value == null || type === "number" && isNaN( value ) ) {
                    return;
                // If a number was passed in, add 'px' to the (except for certain CSS properties)
                //如果传进来的值是number类型,如.css('height',10),则给10加上单位px
                if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
                    value += "px";
                // If a hook was provided, use that value, otherwise just set the specified value
                //如果该属性存在对应钩子对象,且该对象有set方法,则调用刚set方法设置样式值
                if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
                    // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
                    // Fixes bug #5509
                    try {
                        style[ name ] = value;
                    } catch(e) {}
            } else {
                //如果value没有提供,jQuery.css返回内联样式值
                // If a hook was provided get the non-computed value from there
                if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
                    return ret;
                // Otherwise just get the value from the style object
                return style[ name ];
    
  • curCSS  //浏览器内置获取节点样式方法,为(1)遵守支持标准的浏览器:getComputedStyle (2)IE系列:currentStyle
  • //处理遵守W3C标准的浏览器
    //在浏览器里,document.defaultView返回与document相关的window对象,如果不存在,则返回null
    //IE9以下版本的IE系列不支持defaultView
    //其实可以直接window.getComputedStyle,除了一种情况,见:https://developer.mozilla.org/en-US/docs/DOM/window.getComputedStyle
    //getComputedStyle() gives the final used values of all the CSS properties of an element.
    //比如样式表里设置font-size:12px,内联样式设置font-size:20px,返回的是20px
    if ( document.defaultView && document.defaultView.getComputedStyle ) {    //兼容标准的浏览器
        getComputedStyle = function( elem, name ) {
            var ret, defaultView, computedStyle, width,
                style = elem.style;
            name = name.replace( rupper, "-$1" ).toLowerCase();    //将属性名转换成margin-left这种带连字符的形式
                                                                //rupper定义:rupper = /([A-Z]|^ms)/g
            if ( (defaultView = elem.ownerDocument.defaultView) &&
                    (computedStyle = defaultView.getComputedStyle( elem, null )) ) {    //ownerDocument 可返回某元素的根元素,定义见:https://developer.mozilla.org/en-US/docs/DOM/Node.ownerDocument
                                                                                        //getComputedStyle,返回计算后的样式值,定义见:https://developer.mozilla.org/en-US/docs/DOM/window.getComputedStyle
                                                                                        //关于getComputedStyle与computed value、used value的关系:https://developer.mozilla.org/en-US/docs/CSS/computed_value
                ret = computedStyle.getPropertyValue( name );    //
                if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {    //这句的作用??
                    ret = jQuery.style( elem, name );
                //document.documentElement返回文档的的根节点,比如html文档的<html>元素
            // A tribute to the "awesome hack by Dean Edwards"
            // WebKit uses "computed value (percentage if specified)" instead of "used value" for margins
            // which is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values
            //jQuery.support.pixelMargin:是否支持margin返回的结果是px为单位(webkit里面,如果设置了百分值,则返回百分值)??
            //经chrome测试,jQuery.support.pixelMargin === true
            if ( !jQuery.support.pixelMargin && computedStyle && rmargin.test( name ) && rnumnonpx.test( ret ) ) {
                width = style.width;
                style.width = ret;
                ret = computedStyle.width;
                style.width = width;
            return ret;
    //IE浏览器,此处留坑待填
    if ( document.documentElement.currentStyle ) {    //currentStyle:IE浏览器特有的属性
        currentStyle = function( elem, name ) {
            var left, rsLeft, uncomputed,
                ret = elem.currentStyle && elem.currentStyle[ name ],
                style = elem.style;
            // Avoid setting ret to empty string here
            // so we don't default to auto
            if ( ret == null && style && (uncomputed = style[ name ]) ) {
                ret = uncomputed;
            // From the awesome hack by Dean Edwards
            // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
            // If we're not dealing with a regular pixel number
            // but a number that has a weird ending, we need to convert it to pixels
            if ( rnumnonpx.test( ret ) ) {    //rnumnonpx定义:rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i
                // Remember the original values
                left = style.left;
                rsLeft = elem.runtimeStyle && elem.runtimeStyle.left;
                // Put in the new values to get a computed value out
                if ( rsLeft ) {
                    elem.runtimeStyle.left = elem.currentStyle.left;
                style.left = name === "fontSize" ? "1em" : ret;
                ret = style.pixelLeft + "px";
                // Revert the changed values
                style.left = left;
                if ( rsLeft ) {
                    elem.runtimeStyle.left = rsLeft;
            return ret === "" ? "auto" : ret;
    curCSS = getComputedStyle || currentStyle;

    其他相关:

  • jQuery.cssHooks  //钩子函数,某些样式,如'height'、'width'等用到
  • jQuery.extend({
        // Add in style property hooks for overriding the default
        // behavior of getting and setting a style property
        //钩子方法,对一些特殊的属性,需要有特殊的样式读取(get)、设置(set)方法
        cssHooks: {
            //@cssHooks1:透明度
            opacity: {
                get: function( elem, computed ) {
                    if ( computed ) {
                        // We should always get a number back from opacity
                        var ret = curCSS( elem, "opacity" );
                        return ret === "" ? "1" : ret;
                    } else {
                        return elem.style.opacity;
    //@cssHooks3:透明度
    if ( !jQuery.support.opacity ) {    //如果不支持style.opacity,关于support下文有讲到,暂时从字面上理解即可
        jQuery.cssHooks.opacity = {
            get: function( elem, computed ) {
                // IE uses filters for opacity
                return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ?    //IE:是否存在filter:alpha(opacity=30)的样式设置
                    ( parseFloat( RegExp.$1 ) / 100 ) + "" :    //存在:将opacity转换成小数点形式(与遵守标准的浏览器保持一致)
                    computed ? "1" : "";    //不存在:未设置opacity,视为全部透明,即1
            set: function( elem, value ) {
                var style = elem.style,
                    currentStyle = elem.currentStyle,
                    opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "",    //为IE、非IE保持一致,需要乘以100
                    filter = currentStyle && currentStyle.filter || style.filter || "";
                // IE has trouble with opacity if it does not have layout
                // Force it by setting the zoom level
                style.zoom = 1;    //此处为解决IE bug,表示还不知道有这么个bug存在于人世间,重构的兄弟们辛苦了
                // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652
                if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" ) {
                    // Setting style.filter to null, "" & " " still leave "filter:" in the cssText
                    // if "filter:" is present at all, clearType is disabled, we want to avoid this
                    // style.removeAttribute is IE Only, but so apparently is this code path...
                    style.removeAttribute( "filter" );
                    // if there there is no filter style applied in a css rule, we are done
                    if ( currentStyle && !currentStyle.filter ) {
                        return;
                // otherwise, set new filter values
                style.filter = ralpha.test( filter ) ?
                    filter.replace( ralpha, opacity ) :
                    filter + " " + opacity;
    //@cssHooks4:marginRight(右外边距)
    //据说是为了处理神bug存在的,就不伤害自己脑细胞了,了解下即可
    jQuery(function() {
        // This hook cannot be added until DOM ready because the support test
        // for it is not run until after DOM ready
        if ( !jQuery.support.reliableMarginRight ) {
            jQuery.cssHooks.marginRight = {
                get: function( elem, computed ) {
                    // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
                    // Work around by temporarily setting element display to inline-block
                    return jQuery.swap( elem, { "display": "inline-block" }, function() {
                        if ( computed ) {
                            return curCSS( elem, "margin-right" );
                        } else {
                            return elem.style.marginRight;
    // These hooks are used by animate to expand properties
    //@cssHooks5:待填坑
    jQuery.each({
        margin: "",
        padding: "",
        border: "Width"
    }, function( prefix, suffix ) {
        jQuery.cssHooks[ prefix + suffix ] = {
            expand: function( value ) {
                var i,
                    // assumes a single number if not a string
                    parts = typeof value === "string" ? value.split(" ") : [ value ],
                    expanded = {};
                for ( i = 0; i < 4; i++ ) {
                    expanded[ prefix + cssExpand[ i ] + suffix ] =
                        parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
                return expanded;
    //@cssHooks2用到
    function getWidthOrHeight( elem, name, extra ) {
        // Start with offset property
        var val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
            i = name === "width" ? 1 : 0,
            len = 4;
        if ( val > 0 ) {    //此处作用,减去paddingTopWidth、paddingBottomWidth、borderTopWidth、borderBottomWidth,要不要这么隐晦啊啊!!!
            if ( extra !== "border" ) {
                for ( ; i < len; i += 2 ) {
                    if ( !extra ) {
                        val -= parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;
                    if ( extra === "margin" ) {
                        val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ] ) ) || 0;
                    } else {
                        val -= parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
            return val + "px";
        // Fall back to computed then uncomputed css if necessary
        val = curCSS( elem, name );
        if ( val < 0 || val == null ) {    //会有小于0的情况吗???
            val = elem.style[ name ];
        // Computed unit is not pixels. Stop here and return.
        if ( rnumnonpx.test(val) ) {    //val单位非px
            return val;
        // Normalize "", auto, and prepare for extra
        val = parseFloat( val ) || 0;
        // Add padding, border, margin
        //目测:在getClentHeight、getClientWidth等处可以用到
        if ( extra ) {
            for ( ; i < len; i += 2 ) {
                val += parseFloat( jQuery.css( elem, "padding" + cssExpand[ i ] ) ) || 0;
                if ( extra !== "padding" ) {
                    val += parseFloat( jQuery.css( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0;
                if ( extra === "margin" ) {
                    val += parseFloat( jQuery.css( elem, extra + cssExpand[ i ]) ) || 0;
        return val + "px";
    
  • jQuery.support  //浏览器对某些特性的支持,详情见下文
  • //各种测试是否支持某些属性
    //仅将CSS相关部分挑出来,完整的support方法包注释200++行,有兴趣可以看下源码
    jQuery.support = (function(){
        var marginDiv,
            div = document.createElement( "div" );
        div.innerHTML = "   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";    
        var a = div.getElementsByTagName( "a" )[ 0 ];
        var support = {
            // Make sure that element opacity exists
            // (IE uses filter instead)
            // Use a regex to work around a WebKit issue. See #5145
            opacity: /^0.55/.test( a.style.opacity ),    //是否支持opacity==>IE6/7/8采用filter来实现(半)透明效果,
            // Verify style float existence
            // (IE uses styleFloat instead of cssFloat)
            cssFloat: !!a.style.cssFloat,    //(1)IE:node.style.styleFloat(2)chrome等:node.style.cssFloat
            reliableMarginRight: true,        //解决webkit的bug:getComputedStyle返回错误的margin-right值
                                            //解决方案:暂时将节点的display属性设为inline-block
            pixelMargin: true,    //是否支持margin返回的结果是px为单位(webkit里面,如果设置了百分值,则返回百分值),测试了下chrome下是ok的    
        // Check if div with explicit width and no margin-right incorrectly
        // gets computed margin-right based on width of container. For more
        // info see bug #3333
        // Fails in WebKit before Feb 2011 nightlies
        // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
        if ( window.getComputedStyle ) {    //jQuery.support.reliableMarginRight
            div.innerHTML = "";
            marginDiv = document.createElement( "div" );
            marginDiv.style.width = "0";
            marginDiv.style.marginRight = "0";
            div.style.width = "2px";
            div.appendChild( marginDiv );
            support.reliableMarginRight =
                ( parseInt( ( window.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0;
        if ( window.getComputedStyle ) {    //jQuery.support.pixelMargin
            div.style.marginTop = "1%";
            support.pixelMargin = ( window.getComputedStyle( div, null ) || { marginTop: 0 } ).marginTop !== "1%";
        return support;
    })();
  • jQuery.swap  //节点隐藏等情况下,height、width等获取值不准,此时需利用此方法来获得准确值
  • jQuery.extend({
    	// A method for quickly swapping in/out CSS properties to get correct calculations
    	//将offsetHeight、offsetWidth为0的元素快速修改样式,获得需要的值后,再改回去
    	//options:{display:'block',position:'absolute',visibility:'hidden'}
    	 * @description 将offsetHeight、offsetWidth为0(可能因display=none等原因导致)的元素快速修改样式,获得浏览器实际渲染的值后,再改回去
    	 * @param {DOMObject} elem dom节点
    	 * @param {Object} options {display:'block',position:'absolute',visibility:'hidden'}
    	 * @param {Function} callback 回调方法,如获取修改后的dom节点的宽、高等
    	swap: function( elem, options, callback ) {
    		var old = {},
    			ret, name;
    		// Remember the old values, and insert the new ones
    		for ( name in options ) {	//先将dom元素设置为display=block;position=absolute;visibility=hidden;
    			old[ name ] = elem.style[ name ];
    			elem.style[ name ] = options[ name ];
    		ret = callback.call( elem );
    		// Revert the old values
    		for ( name in options ) {	//将改变的display、position、visibiliby设置回去
    			elem.style[ name ] = old[ name ];
    		return ret;
    
  • jQuery.cssProps  //某些属性,在浏览器里有各自的别名,如float:IE里为styleFloat,遵守标准的浏览器里为cssFoat
  • jQuery.extend({
        // Add in properties whose names you wish to fix before
        // setting or getting the value
        //此处的属性名需要特殊处理,如float,在IE里为node.style.styleFloat,支持标准的浏览器里为node.style.cssFloat
        cssProps: {
            // normalize float css property
            "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
    
  • jQuery.cssNumber  //某些属性,如z-index,为数值类型,不需要单位
  • jQuery.extend({
        // Exclude the following css properties to add px
        //排除一下css属性,无需加px,此处有些疑问,如lineHeight,需再研究下。
        cssNumber: {
            "fillOpacity": true,
            "fontWeight": true,
            "lineHeight": true,
            "opacity": true,
            "orphans": true,
            "widows": true,
            "zIndex": true,
            "zoom": true
    

    相关正则等:

    var ralpha = /alpha\([^)]*\)/i,    //匹配如:alpha(opacity=20)
        ropacity = /opacity=([^)]*)/,    //匹配如:filter:alpha(opacity=20)等形式
        // fixed for IE9, see #8346
        rupper = /([A-Z]|^ms)/g,    //此处暂不明,但觉厉,需再探究下
        rnum = /^[\-+]?(?:\d*\.)?\d+$/i,    //匹配数字(包括浮点),如(+/-)1、(+/-)0.1、(+/-).1、(+/-)1.1
        rnumnonpx = /^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,    //非px值,如'10em'、'10%'等
        rrelNum = /^([\-+])=([\-+.\de]+)/,    //设置属性支持相对写法,如$('#header').css('height', '+=10px')等。。
        rmargin = /^margin/,    //属性是否为margin开头的,如margin-left、margin-top等
        cssShow = { position: "absolute", visibility: "hidden", display: "block" },    //对于offsetHeight或offsetWidth为0的元素
        // order is important!
        cssExpand = [ "Top", "Right", "Bottom", "Left" ],    //计算宽、高用到
        curCSS,    //最终只是把getComputedStyle或currentStyle方法其中之一赋给curCss
        getComputedStyle,    //遵守标准的浏览器获取css样式的方法
        currentStyle;    //IE浏览器获取css样式的方法