提前阅读:阅读
css方法源码分析:
css: function( name, value ) { return access( this, function( elem, name, value ) { var styles, len, map = {}, i = 0; //如果传入的第二个参数是数组对象,那么表示获取所有的属性的集合 //var styleObj = $n2.css( ["paddingTop", "paddingRight", "paddingBottom", "paddingLeft"] ); if ( jQuery.isArray( name ) ) { //获取该元素的cssStyleDeclaration对象 styles = getStyles( elem ); len = name.length; //封装到map对象上去,如map["backgroundColor"]=""属性值通过jQuery.css获取 for ( ; i < len; i++ ) { map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); } return map; } //如果value不是空,表示是设置属性,调用jQuery.style设置属性,否则调用jQuery.css获取属性的值返回! return value !== undefined ? jQuery.style( elem, name, value ) : jQuery.css( elem, name ); }, name, value, arguments.length > 1 ); }总结:
(1)底层调用的acess方法,所以如果获取,那么只会获取到第一个调用对象的属性,设置时候会把调用对象中所有的元素都进行设置!
(2)如果传入的是一个对象,那么在access里面会对该对象的任何一对属性值和属性名循环调用调用对象,也就是把这对属性名和属性值都封装到每一个DOM对象上
(3)如果传入的是一个数组,那么表示获取调用对象的第一个元素的所有的数组里面的属性,然后返回一个数组!
jQuery.css源码分析:
css: function( elem, name, extra, styles ) { var num, val, hooks, //获取type的驼峰写法 origName = jQuery.camelCase( name ); //jQuery.cssProps["color"]="color" name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); // gets hook for the prefixed version // followed by the unprefixed version //获取hooks对象 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // If a hook was provided get the computed value from there //如果hooks有get方法那么调用get方法 if ( hooks && "get" in hooks ) { val = hooks.get( elem, true, extra ); } //如果没有get方法继续调用curCss方法 // Otherwise, if a way to get the computed value exists, use that if ( val === undefined ) { val = curCSS( elem, name, styles ); } if ( val === "normal" && name in cssNormalTransform ) { val = cssNormalTransform[ name ]; } //如果extra没空字符串,或者extra存在。那么把返回的结果变成数字 // Return, converting to number if forced or a qualifier was provided and val looks numeric if ( extra === "" || extra ) { num = parseFloat( val ); return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; } //把处理过的结果返回 return val; } });jQuery.style源码分析:
style: function( elem, name, value, extra ) { // Don't set styles on text and comment nodes //不会操作文本节点和注释节点 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { return; } // Make sure that we're working with the right name var ret, type, hooks, origName = jQuery.camelCase( name ), style = elem.style; name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); // gets hook for the prefixed version // followed by the unprefixed version hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // Check if we're setting a value //如果value不是空,表示设置值 if ( value !== undefined ) { type = typeof value; //如果赋值是string类型,同时满足要求 // convert relative number strings (+= or -=) to relative numbers. #7345 //rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ) /* var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; var rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ); alert(rrelNum.test("+=10"));//打印true */ 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 null and NaN values aren't set. See: #7116 if ( value == null || value !== value ) { return; } // If a number was passed in, add 'px' to the (except for certain CSS properties) if ( type === "number" && !jQuery.cssNumber[ origName ] ) { value += "px"; } // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, // but it would mean to define eight (for every problematic property) identical functions if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { style[ name ] = "inherit"; } // If a hook was provided, use that value, otherwise just set the specified value if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { // Support: IE // Swallow errors from 'invalid' CSS values (#5509) 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; } // Otherwise just get the value from the style object return style[ name ]; } }getWithOrHeight源码分析:
function getWidthOrHeight( elem, name, extra ) { // Start with offset property, which is equivalent to the border-box value var valueIsBorderBox = true, //如果是name是width,那么获取offsetWidth,否则获取offsetHeight val = name === "width" ? elem.offsetWidth : elem.offsetHeight, //获取元素的styleDeclaration对象 styles = getStyles( elem ), //是否和IE6之前相同 isBorderBox = support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; // some non-html elements return undefined for offsetWidth, so check for null/undefined // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 //如果获取的offsetWidth,offsetHeight小于0或者是空 if ( val <= 0 || val == null ) { // Fall back to computed then uncomputed css if necessary //如果val<0或者val=null那么通过curCss继续获取如果val<0或者val=null //那么获取elem.style val = curCSS( elem, name, styles ); if ( val < 0 || val == null ) { val = elem.style[ name ]; } //如果计算的不是像素 //var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); // Computed unit is not pixels. Stop here and return. if ( rnumnonpx.test(val) ) { return val; } // we need the check for style in case a browser which returns unreliable values // for getComputedStyle silently falls back to the reliable elem.style valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] ); // Normalize "", auto, and prepare for extra //将val进行转化为数字! val = parseFloat( val ) || 0; } // use the active box-sizing model to add/subtract irrelevant styles return ( val + augmentWidthOrHeight( elem, name, extra || ( isBorderBox ? "border" : "content" ), valueIsBorderBox, styles ) ) + "px"; }getWidthOrHeight总结:先获取该元素的getComputedStyle,或者currentStyle;不满足条件就调用curCss方法;如果还是不满足条件就调用elem.style[""]方法!
argumentWidthOrHeight源码分析:
function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { var i = extra === ( isBorderBox ? "border" : "content" ) ? // If we already have the right measurement, avoid augmentation 4 : // Otherwise initialize for horizontal or vertical properties name === "width" ? 1 : 0, val = 0; for ( ; i < 4; i += 2 ) { // both box models exclude margin, so add it if we want it //如果extra是margin表示我们需要把margin属性添加。因为content-box和border-box都不包含margin if ( extra === "margin" ) { val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); } //如果是IE6之前的模式! if ( isBorderBox ) { // border-box includes padding, so remove it if we want content //border-box包含padding,所以如果只要content那么把padding移除 if ( extra === "content" ) { val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); } // at this point, extra isn't border nor margin, so remove border if ( extra !== "margin" ) { val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } else { // at this point, extra isn't content, so add padding //添加padding val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); // at this point, extra isn't content nor padding, so add border if ( extra !== "padding" ) { val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); } } } return val; }