• jQuery css


    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的styles
                styles = getStyles( elem );
                len = name.length;
    
                //创建对应styles的处理函数map
                for ( ; i < len; i++ ) {
                    map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
                }
    
                return map;
            }
    
            //如果不是数组,则返回jQuery.style或jQuery.css
            return 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 ) );
                // 将其类型改成number
                type = "number";
            }
    
            // 确保NaN和null不被设置
            if ( value == null || type === "number" && isNaN( value ) ) {
                return;
            }
    
            // 如果value是数字则加上px
            if ( 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 );
    
        // 修正名字name
        name = 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 ];
        }
    
        // 是否需要强行转成数字或者true
        if ( 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
            // 将百分比转成更加有用的px
            if ( 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;
    }
  • 相关阅读:
    golang 用tar打包文件或文件夹
    golang 最和谐的子序列
    golang 轮训加密算法
    golang map
    golang 队列
    golang 栈操作
    golang 多维数组
    golang 数组反转
    c# sendmessage control to scroll
    c# 启动的时候向其他程序传值
  • 原文地址:https://www.cnblogs.com/justany/p/2867834.html
Copyright © 2020-2023  润新知