jQuery css模块用于css属性的修改操作。
jQuery.fn.css
jQuery.fn.css = function( name, value ) {//又是用access来操作return jQuery.access( this, function( elem, name, value ) {var styles, len,map = {},i = 0;//如果name是数组if ( jQuery.isArray( name ) ) {//通过getStyles方法返回elem的stylesstyles = getStyles( elem );len = name.length;//创建对应styles的处理函数mapfor ( ; i < len; i++ ) {map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );}return map;}//如果不是数组,则返回jQuery.style或jQuery.cssreturn value !== undefined ?jQuery.style( elem, name, value ) :jQuery.css( elem, name );}, name, value, arguments.length > 1 ); };
又是通过jQuery.access来遍历和操作属性。
根据value值来判断是返回一个函数数组,还是返回一个函数传入jQuery.access。
主要用到jQuery.css和jQuery.style两个方法。
getStyles
function getStyles( elem ) {return window.getComputedStyle( elem, null ); }
这是一个获取实际css style的方法。
可是……getComputedStyle是啥东西……
getComputedStyle
是一个可以获取当前元素所有最终使用的CSS属性值。返回的是一个CSS样式声明对象([object CSSStyleDeclaration]),只读。
语法:
var styles = window.getComputedStyle("元素", "伪类");
如果没有伪类,则传null。
实际上就是获取最终浏览器绘制时的css值,因为style不会返回所有css值,只会返回设置的css值,所以需要用该方法来获得所有css值。
限于篇幅本文就不详细解释了,有兴趣的朋友请参见:获取元素CSS值之getComputedStyle方法熟悉
jQuery.style
jQuery.style = function( elem, name, value, extra ) {// 不处理text和comment节点if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {return;}var ret, type, hooks,//修正css属性名origName = jQuery.camelCase( name ),style = elem.style;//jQuery.cssProps是css缓存,如果有则取出值,否则通过vendorPropName函数来得到实际的css名字name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );// 获取必要的钩子hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];// 如果value已定义if ( value !== undefined ) {type = typeof value;// 如果value是+=或则-=一个数,则转成对应的数字if ( type === "string" && (ret = rrelNum.exec( value )) ) {value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );// 将其类型改成numbertype = "number";}// 确保NaN和null不被设置if ( value == null || type === "number" && isNaN( value ) ) {return;}// 如果value是数字则加上pxif ( type === "number" && !jQuery.cssNumber[ origName ] ) {value += "px";}// 修复#8908,IE9的问题,对于克隆的元素清除掉其background时,其原型的background也会被清除if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {style[ name ] = "inherit";}// 如果钩子存在,则使用钩子设置值,否则用style[ name ]来设置值if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {style[ name ] = value;}} else {// 如果钩子存在,则使用钩子返回值if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {return ret;}// 否则用style[ name ]来返回值return style[ name ];} };
这里面有一个挺有趣的问题。下面两个代码最后结果是多少呢?
alert(("-" + 5) + 6);alert(("-" + 5) * 6);
jQuery.css
jQuery.css = function( elem, name, extra, styles ) {var val, num, hooks,origName = jQuery.camelCase( name );// 修正名字namename = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );// 得到必要的钩子hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];// 如果有钩子则使用get来获取值if ( hooks && "get" in hooks ) {val = hooks.get( elem, true, extra );}// 没有钩子则用curCSS函数获取if ( val === undefined ) {val = curCSS( elem, name, styles );}// 将"normal"转成特定的值if ( val === "normal" && name in cssNormalTransform ) {val = cssNormalTransform[ name ];}// 是否需要强行转成数字或者trueif ( extra === "" || extra ) {num = parseFloat( val );return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;}return val; };
curCSS函数
var curCSS = function( elem, name, _computed ) {var width, minWidth, maxWidth,computed = _computed || getStyles( elem ),// 解决IE9的问题,getPropertyValue用IE9中用.css('filter')ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,style = elem.style;// 如果实际styles数组存在if ( computed ) {//如果ret为"",且elem不是子文档(没有style)if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {ret = jQuery.style( elem, name );}// 支持:Chrome < 17,Safari 5.1// 来自Dean Edwards帅呆的hack// 将百分比转成更加有用的pxif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {// 记住原始值width = style.width;minWidth = style.minWidth;maxWidth = style.maxWidth;// 通过改变minWidth、maxWidth、width得到相应的px值style.minWidth = style.maxWidth = style.width = ret;ret = computed.width;// 再将原来的值赋回去style.width = width;style.minWidth = minWidth;style.maxWidth = maxWidth;}}return ret; };
Dean Edwards的hack主要利用的是部分浏览器会使用计算值来表示元素宽度,而非使用值。
show & hide
jQuery.fn.show = function() {return showHide( this, true ); };
jQuery.fn.show直接引用showHide函数,jQuery.fn.hide也是一样:
jQuery.fn.hide = function() {return showHide( this ); };
而jQuery.fn.toggle则可接受state或者通过判断当前元素是否hidden,再调用jQuery.fn.show或者jQuery.fn.hide。
jQuery.fn.toggle = function( state ) {var bool = typeof state === "boolean";return this.each(function() {if ( bool ? state : isHidden( this ) ) {jQuery( this ).show();} else {jQuery( this ).hide();}}); };
showHide函数
function showHide( elements, show ) {var elem,values = [],index = 0,length = elements.length;// 遍历所有元素for ( ; index < length; index++ ) {elem = elements[ index ];//如果元素没有style属性,则跳过if ( !elem.style ) {continue;}//取出保存在缓存的olddisplay值values[ index ] = jQuery._data( elem, "olddisplay" );//如果要显示if ( show ) {// 通过将display设置成"",来判断""元素是否会显示if ( !values[ index ] && elem.style.display === "none" ) {elem.style.display = "";}// 如果display被设成了"",并且元素隐藏了,则通过css_defaultDisplay设置默认显示方法if ( elem.style.display === "" && isHidden( elem ) ) {values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) );}//如果缓存没有值,且元素没有隐藏} else if ( !values[ index ] && !isHidden( elem ) ) {//将目前的display值保存入缓存jQuery._data( elem, "olddisplay", jQuery.css( elem, "display" ) );}}// 在第二次循环设置display属性,避免不断回流for ( index = 0; index < length; index++ ) {elem = elements[ index ];if ( !elem.style ) {continue;}if ( !show || elem.style.display === "none" || elem.style.display === "" ) {// 是否要西那是,要显示则设置成缓存值或者"",否则设置为"none"elem.style.display = show ? values[ index ] || "" : "none";}}return elements; }