zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    python3 TypeError: a bytes-like object is required, not 'str'
    Centos 安装Python Scrapy PhantomJS
    Linux alias
    Vim vimrc配置
    Windows下 Python Selenium PhantomJS 抓取网页并截图
    Linux sort
    Linux RSync 搭建
    SSH隧道 访问内网机
    笔记《鸟哥的Linux私房菜》7 Linux档案与目录管理
    Tornado 错误 "Global name 'memoryview' is not defined"
  • 原文地址:https://www.cnblogs.com/justany/p/2867834.html
Copyright © 2011-2022 走看看