.css()的用法:
jQuery.fn.css()有4种用法,第一种是读取样式属性值,其余三种是设置样式属性值:
.css( propertyName ) 获取第一个元素的样式属性值,propertyName是CSS属性名
.css( propertyName, value ) 在匹配的元素集上设置一个CSS属性,value是要设置的属性值
.css( propertyName, function(index, value) ) 将函数返回值做为属性值设置
function(index, value) 返回要设置的属性值,函数的上下文this指向当前元素,接收两个参数:index是当前元素在集合中的下标位置;value是旧值,即当前值(意味着设置之前要先取出当前值)
.css( map ) 设置多个样式
map 含有键值对的map,键是属性名,值是字面直接量或函数
源码分析:.css()方法内部调用.style()用来在DOM节点上读取或设置属性样式 ,用.css()在DOM元素上读取DOM样式值。
jQuery.fn.css = function( name, value ) { //如果有一个参数为undefined 不做任何操作 返回this if ( arguments.length === 2 && value === undefined ) { return this; } //对this进行遍历,并执行参数中的函数 调用jQuery.access执行fn return jQuery.access( this, name, value, true, function( elem, name, value ) { return value !== undefined ? //在DOM节点上读取或设置样式属性 style property jQuery.style( elem, name, value ) ://设值 包括value是空字符串 //在DOM元素上读取DOM样式值 jQuery.css( elem, name );//取值 }); };
.style()方法和.css()方法源码分析:
JS
//便于操作的钩子 jQuery.extend({ //css钩子 cssHooks: { opacity: { get: function( elem, computed ) { if ( computed ) { var ret = curCSS( elem, "opacity", "opacity" ); return ret === "" ? "1" : ret; } else { return elem.style.opacity; } } } }, cssNumber: { "zIndex": true, "fontWeight": true, "opacity": true, "zoom": true, "lineHeight": true, "widows": true, "orphans": true }, //prop钩子,处理float cssProps: { "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" }, /* 1. 过滤Text和Comment,过滤无style的元素,返回undefined 2. 转换为驼峰式,修正属性名 3. 如果是设置: 如果是number,过滤NaN;过滤null;如果是相对值字符串,计算 添加后缀 如果存在钩子,则调用钩子的set;如果没有钩子,则设置style[ name ] = value; 4. 如果是读取: 如果存在钩子,则调用钩子的get;如果没有钩子,则返回style[ name ] */ //在DOM节点上读取或设置样式属性 style property style: function( elem, name, value, extra ) { //过滤掉text和comment 过滤掉没有style属性的元素 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { return; } //将name转换为驼峰式,修正属性名 确保使用了正确的名字 var ret, type, origName = jQuery.camelCase( name ), style = elem.style, hooks = jQuery.cssHooks[ origName ];//转换为驼峰格式 //修正属性名,是否在不同的浏览器中使用不同的属性名 name = jQuery.cssProps[ origName ] || origName;//CSS钩子 //设置 if ( value !== undefined ) { type = typeof value;//值的类型 /* 1.7: if(type === "string" && (ret = rrelNum.test( value )) ){ //ret[1]正负号 ret[2]相对值 //+(ret[1] + 1 ret[1]是字符串 加上1 变成 +1 或 -1,最后边的加号将字符串转换成1 或 -1 //+ret[2]同样将ret[2]转换为数字 parseFloat(jQuery.css(elem,name)):当前值 value = (+(ret[1] + 1)* + ret[2]) + parseFloat(jQuery.css(elem,name)); type = "number"; } */ //过滤NAN null 不做任何处理 if ( type === "number" && isNaN( value ) || value == null ) { return; } //计算相对值rrelNum = /^([\-+])=([\-+.\de]+)/ if ( type === "string" && rrelNum.test( value ) ) { value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) ); } //如果是数字 追加单位px if ( type === "number" && !jQuery.cssNumber[ origName ] ) { value += "px"; } /* * 如果有钩子hooks,且hooks中存在set函数,则调用hooks.set,将返回值赋给value * 如果hooks.set的返回值为undefined,则不执行任何操作;返回值不为undefined,则用新value设置样式值 * 简单点说,有hooks.set则调用,用返回值替换value,最后设置style.name;否则直接设置style.name * 可见钩子的作用是修正属性值,并不直接对值进行设置 */ if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) { //用try catch 块 预防IE中用到不合法的值设置样式时,抛出异常 try { style[ name ] = value; } catch(e) {} } //读取 } else { // 如果有钩子hooks,则调用hooks.get,返回值赋给ret if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { return ret; } // 否则从style对象中读取属性值 return style[ name ]; } }, css: function( elem, name, extra ) { var ret, hooks; name = jQuery.camelCase( name );//转换为驼峰式 hooks = jQuery.cssHooks[ name ];//是否有钩子 name = jQuery.cssProps[ name ] || name;//修正属性名 //cssFloat特殊处理 if ( name === "cssFloat" ) { name = "float"; } // 如果钩子hooks存在,则调用hooks.get计算样式值,并返回 if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { return ret; // 否则,如果curCSS存在,则调用curCSS获取计算后的样式值,并返回 } else if ( curCSS ) { return curCSS( elem, name ); } }, // A method for quickly swapping in/out CSS properties to get correct calculations swap: function( elem, options, callback ) { var old = {}; // Remember the old values, and insert the new ones for ( var name in options ) { old[ name ] = elem.style[ name ]; elem.style[ name ] = options[ name ]; } callback.call( elem ); // Revert the old values for ( name in options ) { elem.style[ name ] = old[ name ]; } }, //将命名规则转换为驼峰式的 ?? camelCase: function( string ) { return string.replace( rdashAlpha, fcamelCase ); } });
解决浏览器获取属性的兼容问题源码:
/* IE为每个元素提供的currentStyle对象; DOM则从document.defaultView对象中访问getComputedStyle()方法; document.defaultView.getComputedStyle 这是w3c标准方法,取得元素的样式信息, 因为有些样式是在外部css文件定义的,所以用element.style是取不到的 如果是IE,可以用 element.currentStyle["name"] */ if ( document.defaultView && document.defaultView.getComputedStyle ) { getComputedStyle = function( elem, name ) { var ret, defaultView, computedStyle;//预定义变量 //将驼峰式转换成连字符 例如:marginTop > margin-top name = name.replace( rupper, "-$1" ).toLowerCase(); /* * 分解: * var defaultView = elem && elem.ownerDocument.defaultView; * var computedStyle = defaultView && defaultView.getComputedStyle( elem, null ); * var ret = computedStyle && computedStyle.getPropertyValue( name ); * return ret; */ if ( (defaultView = elem.ownerDocument.defaultView)&&(computedStyle = defaultView.getComputedStyle( elem, null )) ) { ret = computedStyle.getPropertyValue( name ); if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) { ret = jQuery.style( elem, name ); } } return ret; }; } //IE下 if ( document.documentElement.currentStyle ) { currentStyle = function( elem, name ) { var left, ret = elem.currentStyle && elem.currentStyle[ name ],//直接取值 rsLeft = elem.runtimeStyle && elem.runtimeStyle[ name ], style = elem.style; if ( !rnumpx.test( ret ) && rnum.test( ret ) ) { // Remember the original values left = style.left; // Put in the new values to get a computed value out if ( rsLeft ) { elem.runtimeStyle.left = elem.currentStyle.left; } style.left = name === "fontSize" ? "1em" : (ret || 0); ret = style.pixelLeft + "px"; // Revert the changed values style.left = left; if ( rsLeft ) { elem.runtimeStyle.left = rsLeft; } } return ret === "" ? "auto" : ret; }; } curCSS = getComputedStyle || currentStyle; jQuery.curCSS = jQuery.css;