• jQuery 样式处理


    jQuery.fn.css = function( name, value ) {
      if ( arguments.length === 2 && value === undefined ) {
        return this;
      }
      return jQuery.access( this, name, value, true, function( elem, name, value ) {
          return value !== undefined ?jQuery.style( elem, name, value ) : jQuery.css( elem, name );
        });
    };    
    jQuery处理样式,如果参数长度为2,而vlaue值undefined,则无需赋值直接返回。否则返回jQuery.access操作结果
    access: function( elems, key, value, exec, fn, pass ) {
            var length = elems.length;
        if ( typeof key === "object" ) {
            for ( var k in key ) {
                jQuery.access( elems, k, key[k], exec, fn, value);
            }
            return elems;
        }
        if ( value !== undefined ) {
            exec = !pass && exec && jQuery.isFunction(value);
                    for ( var i = 0; i < length; i++ ) {
                fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
            }
                return elems;
        }
           return length ? fn( elems[0], key ) : undefined;
    }              

    内部公用方法access,首先会先通过判断key的类型是否为object,如果为真,则通过递归的方式把每个key[k]作为的属性分别进行操作。

    if ( typeof key === "object" ) {
            for ( var k in key ) {
                jQuery.access( elems, k, key[k], exec, fn, value);
            }
            return elems;
        }

    然后对单个节点进行操作,判断value!==underfined,true则通过传入的方法fn设置属性key[k]的值并返回对象集elems,false则返回属性的值

    if ( value !== undefined ) {
            exec = !pass && exec && jQuery.isFunction(value);
                    for ( var i = 0; i < length; i++ ) {
                fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass );
            }
                return elems;
        }
    return length ? fn( elems[0], key ) : undefined;
    在这里,fn为:

    function( elem, name, value ) {
      return value !== undefined ?jQuery.style( elem, name, value ) :jQuery.css( elem, name );
    }

    通过判断传入的value来判断是否是设置节点elem样式name的值value:jQuery.style( elem, name, value )或者获取elem样式name的值:jQuery.css( elem, name ).

    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
        },
        cssProps: {//
            "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat"
        },
        style: function( elem, name, value, extra ) {
            if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
                return;
            }
            var ret, type, origName = jQuery.camelCase( name ),
               style = elem.style, hooks = jQuery.cssHooks[ origName ];
    
            name = jQuery.cssProps[ origName ] || origName;
            if ( value !== undefined ) {
                type = typeof value;
                if ( type === "number" && isNaN( value ) || value == null ) {
                    return;
                }
    ative number strings (+= or -=) to relative numbers. #7345
                if ( type === "string" && rrelNum.test( value ) ) {
                    value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
                }
                if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
                    value += "px";
                }
                if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {
                    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;
                }
                return style[ name ];
            }
        },
    
        css: function( elem, name, extra ) {
            var ret, hooks;
            name = jQuery.camelCase( name );
            hooks = jQuery.cssHooks[ name ];
            name = jQuery.cssProps[ name ] || name;//
    
            if ( name === "cssFloat" ) {
                name = "float";
            }
    
            if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {
                return ret;
            } else if ( curCSS ) {
                return curCSS( elem, name );
            }
        },
    
        swap: function( elem, options, callback ) {
            var old = {};
            for ( var name in options ) {
                old[ name ] = elem.style[ name ];
                elem.style[ name ] = options[ name ];
            }
    
            callback.call( elem );
    
            for ( name in options ) {
                elem.style[ name ] = old[ name ];
            }
        },
    
        camelCase: function( string ) {
            return string.replace( rdashAlpha, fcamelCase );
        }
    cssHooks://特别处理的属性
    cssNumber://排除下面的CSS属性添加PX
    cssProps://浮动属性
    camelCase://对有中线的样式名转换成驼峰写法,如:image-position:imagePosition
    设置样式值
     style: function( elem, name, value, extra ) {
            if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {//elem不存在,文本节点,注释节点,没有style则返回
                return;
            }
            var ret, type, origName = jQuery.camelCase( name ),
               style = elem.style, hooks = jQuery.cssHooks[ origName ];
    
            name = jQuery.cssProps[ origName ] || origName;
            if ( value !== undefined ) {
                type = typeof value;
                if ( type === "number" && isNaN( value ) || value == null ) {//
                    return;
                }
                if ( type === "string" && rrelNum.test( value ) ) {//例如+=2123asd  -=1231203排序叫撒旦过滤后对属性数值进行加减+2123 -1231203
                    value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) );
                }
                if ( type === "number" && !jQuery.cssNumber[ origName ] ) {//对非规定的样式和不带单位的参数,默认加上单位“px”
                    value += "px";
                }
                if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {//对特殊样式,用hooks.set()方法进行设置
                    try {
                        style[ name ] = value;
                    } catch(e) {}
                }
    
            } else {//
                if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {
                    return ret;
                }
                return style[ name ];//直接通过style属性获取name样式的值
            }
        }
    获取样式值:
    css: function( elem, name, extra ) {
            var ret, hooks;
            name = jQuery.camelCase( name );//样式名转换成驼峰写法
            hooks = jQuery.cssHooks[ name ];//判断是否是特殊样式
            name = jQuery.cssProps[ name ] || name;//是否是浮动样式以便后面转换
    
            if ( name === "cssFloat" ) {//针对ie
                name = "float";
            }
    
            if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {//如果是特殊样式则通过hooks.get(elem,true,extra)处理并返回结果
                return ret;
            } else if ( curCSS ) {
                return curCSS( elem, name );//否则通过curCSS返回执行的结果
            }
        },
    curCSS:
    if ( document.defaultView && document.defaultView.getComputedStyle ) {
        getComputedStyle = function( elem, name ) {
            var ret, defaultView, computedStyle;
    
            name = name.replace( rupper, "-$1" ).toLowerCase();
    
            if ( !(defaultView = elem.ownerDocument.defaultView) ) {
                return undefined;
            }
    
            if ( (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
                ret = computedStyle.getPropertyValue( name );
                if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {
                    ret = jQuery.style( elem, name );
                }
            }
    
            return ret;
        };
    }
    
    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;
    
            // From the awesome hack by Dean Edwards
            // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291
    
            // If we're not dealing with a regular pixel number
            // but a number that has a weird ending, we need to convert it to pixels
            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.css(elem,name)是通过curCSS计算最终样式

     
  • 相关阅读:
    javascript 的继承实例
    [转载]编写高性能js
    弹出菜单
    xml xpath dta笔记
    jquery 学习笔记
    公用的css
    谷歌主页动画效果——利用视距暂留原理
    javascript 新知识
    ie6/7 bug大全
    javascript 原生实现 jquery live/delegate
  • 原文地址:https://www.cnblogs.com/tellme/p/2784890.html
Copyright © 2020-2023  润新知