jQuery源码分析之css方法

提前阅读:阅读

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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值