jQuery中css()源码分析

function getStyles( elem ) {
	//这里没有做兼容处理,IE6~8是不支持getComputedStyle()方法,但是有currentStyle属性
	return window.getComputedStyle( elem, null );
}

元素的style属性,只能获取行间样式,可以设置样式,也能获取行间的复合样式

getComputedstyle()可以获取非行间样式,即得到最终样式,只能读取单一样式,不能获取复合样式,不能设置样式。

style可以得到已经创建但没有添加到页面的元素的css属性值,而getComputedstyle()不能

var oDiv = document.createElement('div');
    oDiv.style.width = '100px';
    oDiv.style.height = '100px';
    console.log(oDiv.style.width);//100px
    console.log(getComputedStyle(oDiv,null).width);//没有输出

将创建的元素添加到页面后,两者都可以得到css属性值

var oDiv = document.createElement('div');
    oDiv.style.width = '100px';
    oDiv.style.height = '100px';
    document.body.appendChild(oDiv);
    console.log(oDiv.style.width);//100px
    console.log(getComputedStyle(oDiv,null).width);//100px
});

css样式设置和获取:

console.log($('#div1').css('color'));//单值获取
console.log($('#div1').css(['color','backgroundColor','width']));//多值获取,结果是json对象
$('#div1').css('color','yellow');//单值设置
$('#div1').css({width:200,height:200})//多值设置
$('#div1').css('width',function(){
		return 500;
	});//回调设置

原生js不支持连字符命名的,只支持驼峰式命名,但是jQuery两种方式都支持

$('#div1').css('backgroundColor','red');
$('#div1').css('background-color','red');//在jQuery内部将background-color转化成了backgroundColor

由于float是关键字,在js中获取浮动的属性值时,用cssFloat代替float

但是在jQuery中可以直接写float,因为jQuery内部将float转化成cssFloat

console.log($('#div1').get(0).style.cssFloat);//left 
	console.log($('#div1').get(0).style.float);//left 虽然得到了结果,但是float是关键字
	console.log(getComputedStyle($('#div1').get(0),null).cssFloat);//left 
	console.log($('#div1').css('float'));//left ,jQuery内部将字符串float转化成cssFloat

得到宽度的两种方式(注意单位):

console.log($('#div1').css('width'));//100px
	console.log($('#div1').width());//100

返回元素的css属性值

curCSS = function( elem, name, _computed ) {
	var width, minWidth, maxWidth,
		computed = _computed || getStyles( elem ),

		// Support: IE9
		// getPropertyValue is only needed for .css('filter') in IE9, see #12537
		ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
		style = elem.style;

	if ( computed ) {
         //处理还没有添加到页面的元素的css的属性

		if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
			ret = jQuery.style( elem, name );
		}

		//Safari 5.1处理类似margin-left:10%,不能转换为具体数值+px,style虽然是行间样式,但是可以写,
		//width:10%,可以转化,先将width宽度设置和margin相同,得到结果,再将宽度还原。
		//不管是否存在该行间样式,先保存,将ret这个百分数赋值每个属性,width显示的是数值px
		if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {

			// Remember the original values
			width = style.width;
			minWidth = style.minWidth;
			maxWidth = style.maxWidth;

			// Put in the new values to get a computed value out
			style.minWidth = style.maxWidth = style.width = ret;
			ret = computed.width;

			// Revert the changed values
			style.width = width;
			style.minWidth = minWidth;
			style.maxWidth = maxWidth;
		}
	}

	return ret;
};


jQuery.extend({
	// Add in style property hooks for overriding the default
	// behavior of getting and setting a style property
	cssHooks: {
		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;
				}
			}
		}
	},

	// Don't automatically add "px" to these possibly-unitless properties
	cssNumber: {
		"columnCount": true,
		"fillOpacity": true,
		"fontWeight": true,
		"lineHeight": true,
		"opacity": true,
		"order": true,
		"orphans": true,
		"widows": true,
		"zIndex": true,
		"zoom": true
	},

	// Add in properties whose names you wish to fix before
	// setting or getting the value
	cssProps: {
		// normalize float css property
		"float": "cssFloat"
	},

	// Get and set the style property on a DOM Node
	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
		if ( value !== undefined ) {
			type = typeof value;

			// convert relative number strings (+= or -=) to relative numbers. #7345
			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
			if ( value == null || type === "number" && isNaN( 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 specifying setters in cssHooks,
			// but it would mean to define eight (for every problematic property) identical functions
			if ( !jQuery.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 ) {
				style[ name ] = value;
			}

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

	css: function( elem, name, extra, styles ) {
		var val, num, hooks,
			origName = jQuery.camelCase( name );

		// Make sure that we're working with the right name
		name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );

		// gets hook for the prefixed version
		// followed by the unprefixed version
		hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];

		// If a hook was provided get the computed value from there
		//opacity在没有设置时,会返回空,但实际是1,需要做特殊处理
		if ( hooks && "get" in hooks ) {
			val = hooks.get( elem, true, extra );
		}

		// Otherwise, if a way to get the computed value exists, use that
		if ( val === undefined ) {
			val = curCSS( elem, name, styles );
		}

		//convert "normal" to computed value
		/*cssNormalTransform = {
		letterSpacing: 0,
		fontWeight: 400
	},normal表示一些默认的值,需要转化为对应的数值*/
		if ( val === "normal" && name in cssNormalTransform ) {
			val = cssNormalTransform[ name ];
		}

		// Return, converting to number if forced or a qualifier was provided and val looks numeric
		/*$('#div1').css('width');   '123px'
	      $('#div1').width();    123不带单位,width()源码中会调用jQuery.css(),通过参数extra来去掉单位
*/
		if ( extra === "" || extra ) {
			num = parseFloat( val );
			return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
		}
		return val;
	}
});

jQuery.fn.extend({
	css: function( name, value ) {
		return jQuery.access( this, function( elem, name, value ) {
			var styles, len,
				map = {},
				i = 0;
            //用来处理$('#div1').css(['color','backgroundColor','width'])
			if ( jQuery.isArray( name ) ) {
				styles = getStyles( elem );
				len = name.length;

				for ( ; i < len; i++ ) {
					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
				}

				return map;
			}

			return value !== undefined ?
				jQuery.style( elem, name, value ) :
				jQuery.css( elem, name );
		}, name, value, arguments.length > 1 );
	}
});


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值