提前阅读:阅读
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;
}