function vendorPropName( style, name ) { //检测浏览器前缀} function getStyles( elem ) {//get computed style} function showHide( elements, show ) {//显示隐藏元素,使用data_priv来保存display} jQuery.fn.extend({//拓展四个方法 css: function() {} show: function() {} hide: function() {} toggle: function() {} }) jQuery.extend({ //几个静态方法,最重要的两个静态方法css和style就是在这里定义的 cssHooks: function() {} cssNumber: function() {} style: function() {} css: function() {} }) //下面是几个工具方法 curCSS = function( elem, name, _computed ) {} function augmentWidthOrHeight() {} function getWidthOrHeight( elem, name, extra ) { //下面是对height和width的hook jQuery.each([ "height", "width" ], function( i, name ) {}) …二,jQuery.css和jQuery.style
css返回的是computedStyle,也就是包括父元素的样式,并且css只能读不能写(computedStyle是计算结果而不是一个属性,显然没法修改)
style: function( elem, name, value, extra ) { //style方法是读写元素的自身样式,而不计算继承来的样式 // 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; //检测浏览器前缀,并且会缓存在jQuery.cssProps中 name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); // gets hook for the prefixed version // followed by the unprefixed version //取hook hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; // Check if we're setting a value if ( value !== undefined ) { type = typeof value; //下面三个if都是对数字的处理 // 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) //如果name不在jQuery.cssNumber中,则自动追加’px’,所以,可以通过在jQuery.cssNumber中添加属性的方式来修改这一行为 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 //自动把没有显示声明的属性改成’inherit' 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 // 如果有hook,则调用hook中的set方法来设置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 //如果有hook,则调用hook中的get方法来取value 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 ) { // css 是读取计算后的样式 var val, num, hooks, origName = jQuery.camelCase( name ); // Make sure that we're working with the right name //和style中是一样的,检测浏览器前缀 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 // 使用hook.get 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 ) { // 调用curCSS,得到的是计算后的样式 val = curCSS( elem, name, styles ); } //convert "normal" to computed value if ( val === "normal" && name in cssNormalTransform ) { val = cssNormalTransform[ name ]; } // 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.each([ "height", "width" ], function( i, name ) { jQuery.cssHooks[ name ] = { get: function( elem, computed, extra ) { if ( computed ) { // certain elements can have dimension info if we invisibly show them // however, it must have a current display style that would benefit from this return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ? jQuery.swap( elem, cssShow, function() { return getWidthOrHeight( elem, name, extra ); }) : getWidthOrHeight( elem, name, extra ); } }, set: function( elem, value, extra ) { var styles = extra && getStyles( elem ); return setPositiveNumber( elem, value, extra ? augmentWidthOrHeight( elem, name, extra, jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", styles ) : 0 ); } }; });
jQuery.cssHooks[ ‘abc' ] = { get: function(elem, computed, extra) { return ' I am abc' } }