jQuery.fn.css = function( name, value ) {
  if ( arguments.length === 2 && value === undefined ) {
    return this;
  }
  return jQuery.access( this, name, value, true, function( elem, name, value ) {
      return value !== undefined ?jQuery.style( elem, name, value ) : jQuery.css( elem, name );
    });
};    
jQuery处理样式,如果参数长度为2,而vlaue值undefined,则无需赋值直接返回。否则返回jQuery.access操作结果
access: function( elems, key, value, exec, fn, pass ) {
        var length = elems.length;
    if ( typeof key === "object" ) {
        for ( var k in key ) {
            jQuery.access( elems, k, key[k], exec, fn, value);
        }
        return elems;
    }
    if ( value !== undefined ) {
        exec = !pass && exec && jQuery.isFunction(value);
                for ( var i = 0; i < length; i++ ) {
            fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
        }
            return elems;
    }
       return length ? fn( elems[0], key ) : undefined;
}              

内部公用方法access,首先会先通过判断key的类型是否为object,如果为真,则通过递归的方式把每个key[k]作为的属性分别进行操作。

if ( typeof key === "object" ) {
        for ( var k in key ) {
            jQuery.access( elems, k, key[k], exec, fn, value);
        }
        return elems;
    }

然后对单个节点进行操作,判断value!==underfined,true则通过传入的方法fn设置属性key[k]的值并返回对象集elems,false则返回属性的值

if ( value !== undefined ) {
        exec = !pass && exec && jQuery.isFunction(value);
                for ( var i = 0; i < length; i++ ) {
            fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
        }
            return elems;
    }
return length ? fn( elems[0], key ) : undefined;
在这里,fn为:

function( elem, name, value ) {
  return value !== undefined ?jQuery.style( elem, name, value ) :jQuery.css( elem, name );
}

通过判断传入的value来判断是否是设置节点elem样式name的值value:jQuery.style( elem, name, value )或者获取elem样式name的值:jQuery.css( elem, name ).

cssHooks: {//特别处理的属性
    opacity: {
        get: function( elem, computed ) {
        if ( computed ) {
            var ret = curCSS( elem, "opacity", "opacity" );
            return ret === "" ? "1" : ret;
        } else {
            return elem.style.opacity;
        }
    }
     }
},
    cssNumber: {//
        "zIndex": true,
        "fontWeight": true,
        "opacity": true,
        "zoom": true,
        "lineHeight": true,
        "widows": true,
        "orphans": true
    },
    cssProps: {//
        "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
    },
    style: function( elem, name, value, extra ) {
        if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
            return;
        }
        var ret, type, origName = jQuery.camelCase( name ),
           style = elem.style, hooks = jQuery.cssHooks[ origName ];

        name = jQuery.cssProps[ origName ] || origName;
        if ( value !== undefined ) {
            type = typeof value;
            if ( type === "number" && isNaN( value ) || value == null ) {
                return;
            }
ative number strings (+= or -=) to relative numbers. #7345
            if ( type === "string" && rrelNum.test( value ) ) {
                value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
            }
            if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
                value += "px";
            }
            if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
                try {
                    style[ name ] = value;
                } catch(e) {}
            }

        } else {
            // 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;
            }
            return style[ name ];
        }
    },

    css: function( elem, name, extra ) {
        var ret, hooks;
        name = jQuery.camelCase( name );
        hooks = jQuery.cssHooks[ name ];
        name = jQuery.cssProps[ name ] || name;//

        if ( name === "cssFloat" ) {
            name = "float";
        }

        if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
            return ret;
        } else if ( curCSS ) {
            return curCSS( elem, name );
        }
    },

    swap: function( elem, options, callback ) {
        var old = {};
        for ( var name in options ) {
            old[ name ] = elem.style[ name ];
            elem.style[ name ] = options[ name ];
        }

        callback.call( elem );

        for ( name in options ) {
            elem.style[ name ] = old[ name ];
        }
    },

    camelCase: function( string ) {
        return string.replace( rdashAlpha, fcamelCase );
    }
cssHooks://特别处理的属性
cssNumber://排除下面的CSS属性添加PX
cssProps://浮动属性
camelCase://对有中线的样式名转换成驼峰写法,如:image-position:imagePosition
设置样式值
 style: function( elem, name, value, extra ) {
        if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {//elem不存在,文本节点,注释节点,没有style则返回
            return;
        }
        var ret, type, origName = jQuery.camelCase( name ),
           style = elem.style, hooks = jQuery.cssHooks[ origName ];

        name = jQuery.cssProps[ origName ] || origName;
        if ( value !== undefined ) {
            type = typeof value;
            if ( type === "number" && isNaN( value ) || value == null ) {//
                return;
            }
            if ( type === "string" && rrelNum.test( value ) ) {//例如+=2123asd  -=1231203排序叫撒旦过滤后对属性数值进行加减+2123 -1231203
                value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
            }
            if ( type === "number" && !jQuery.cssNumber[ origName ] ) {//对非规定的样式和不带单位的参数,默认加上单位“px”
                value += "px";
            }
            if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {//对特殊样式,用hooks.set()方法进行设置
                try {
                    style[ name ] = value;
                } catch(e) {}
            }

        } else {//
            if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
                return ret;
            }
            return style[ name ];//直接通过style属性获取name样式的值
        }
    }
获取样式值:
css: function( elem, name, extra ) {
        var ret, hooks;
        name = jQuery.camelCase( name );//样式名转换成驼峰写法
        hooks = jQuery.cssHooks[ name ];//判断是否是特殊样式
        name = jQuery.cssProps[ name ] || name;//是否是浮动样式以便后面转换

        if ( name === "cssFloat" ) {//针对ie
            name = "float";
        }

        if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {//如果是特殊样式则通过hooks.get(elem,true,extra)处理并返回结果
            return ret;
        } else if ( curCSS ) {
            return curCSS( elem, name );//否则通过curCSS返回执行的结果
        }
    },
curCSS:
if ( document.defaultView && document.defaultView.getComputedStyle ) {
    getComputedStyle = function( elem, name ) {
        var ret, defaultView, computedStyle;

        name = name.replace( rupper, "-$1" ).toLowerCase();

        if ( !(defaultView = elem.ownerDocument.defaultView) ) {
            return undefined;
        }

        if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
            ret = computedStyle.getPropertyValue( name );
            if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
                ret = jQuery.style( elem, name );
            }
        }

        return ret;
    };
}

if ( document.documentElement.currentStyle ) {
    currentStyle = function( elem, name ) {
        var left,
            ret = elem.currentStyle && elem.currentStyle[ name ],
            rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ],
            style = elem.style;

        // 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 ( !rnumpx.test( ret ) && rnum.test( ret ) ) {
            // Remember the original values
            left = style.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 || 0);
            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.css(elem,name)是通过curCSS计算最终样式

 
 posted on 2012-11-26 15:38  不知道用什么名字  阅读(1417)  评论(0编辑  收藏  举报