jQuery 源碼解析(二十六) 樣式操做模塊 樣式詳解

樣式操做模塊可用於管理DOM元素的樣式、座標和尺寸,本節講解一下樣式相關,樣式操做經過jQuery實例的css方法來實現,該方法有不少的執行方法,以下:css

  • css(obj)             ;參數1是一個對象時,表示一次性設置多個css樣式  
  • css(name,func)       ;參數2是函數時,設置的是函數返回值    
  • css(name,'')            ;參數2是空字符串時,表示刪除該樣式(刪除style屬性上的)   
  • css(name)              ;若是忽略第二個參數,則獲取第一個匹配元素的name樣式
  • css(name,value)    ;設置每一個匹配的元素的name樣式爲值value。

 writer by:大沙漠 QQ:22969969html

舉個栗子:node

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="http://libs.baidu.com/jquery/1.7.1/jquery.min.js"></script>
    <style>
        div{width: 200px;height: 200px;background: #0ff;}
    </style>
</head>
<body>
    <div>
        
    </div>
    <button id="b1">設置背景和邊框</button>
    <button id="b2">移除邊框</button>
    <button id="b3">獲取寬度</button>
    <script>
        $('#b1').click(()=>{
            $('div').css({background:'#ff0',border:'1px solid #f00'})
        })
        $('#b2').click(()=>{
            $('div').css('border','')
        })
        $('#b3').click(()=>{
            $('div').text($('div').css('height') )
             
        })
    </script>
</body>
</html>

效果以下:jquery

咱們設置了三個按鈕,分別經過css方法進行設置、刪除和獲取樣式,比較好用哈數組

 

源碼分析瀏覽器


jquery實例css方法實現以下:app

jQuery.fn.css = function( name, value ) {            //獲取匹配元素集合中第一個元素的計算樣式 或者 在每一個匹配元素上設置一個或多個內聯樣式。
    // Setting 'undefined' is a no-op
    if ( arguments.length === 2 && value === undefined ) {
        return this;
    }

    return jQuery.access( this, name, value, true, function( elem, name, value ) {        //調用jQuery.access()遍歷匹配元素集合,並在每一個元素上執行傳入的回調函數
        return value !== undefined ?
            jQuery.style( elem, name, value ) :             //若是傳入了參數則調用jQuery.style()設置內聯樣式
            jQuery.css( elem, name );                        //不然調用jQuery.css()來讀取計算樣式
    });
};

經過access工具函數來實現的,這樣參數就支持多種形式了,access在html篇裏講解過了,能夠看這個地址:http://www.javashuo.com/article/p-nwicpnac-e.htmlide

能夠源碼看到,jQuery內部對於css的實現是經過靜態的style和css方法來實現的,前者負責設置DOM元素的內聯樣式,後者用於讀取elem元素上name的值,style的實現以下:函數

jQuery.extend({
    style: function( elem, name, value, extra ) {                //讀取或設置DOM元素的內聯樣式。elem:DOM元素、name:待讀取或設置的樣式名、value:待設置的樣式值、extra:用於指示獲取寬度、高度的計算公式字符串。
        // Don't set styles on text and comment nodes
        if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {    //若是是文本節點或註釋節點 或者不是文本、註釋節點可是沒有style屬性
            return;                                                                        //直接返回,不作處理
        }

        // Make sure that we're working with the right name
        var ret, type, origName = jQuery.camelCase( name ),
            style = elem.style, hooks = jQuery.cssHooks[ origName ];    //將style設置爲elem.style

        name = jQuery.cssProps[ origName ] || origName;

        // Check if we're setting a value
        if ( value !== undefined ) {                                    //若是傳入了value值,則設置相對值。
            type = typeof value;

            // convert relative number strings (+= or -=) to relative numbers. #7345
            if ( type === "string" && (ret = rrelNum.exec( value )) ) {        //若是value是相對值字符串,則計算相對值。value格式是+=..或-=...。rrelNum = /^([\-+])=([\-+.\de]+)/,
                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 ) ) {    //過濾null、NaN類型,不作任何處理,若是要刪除某個內聯樣式,請傳入空字符串
                return;
            }

            // If a number was passed in, add 'px' to the (except for certain CSS properties)
            if ( type === "number" && !jQuery.cssNumber[ origName ] ) {        //若是待設置的樣式值是一個數值,且該樣式不在cssNumber中定義的,則自動追加單位px。cssNumber定義在6492行,是一個數組。
                value += "px";
            }

            // If a hook was provided, use that value, otherwise just set the specified value
            if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value )) !== undefined ) {    //優先調用修正對象愛那個的修正方法set();
                // Wrapped to prevent IE from throwing errors when 'invalid' values are provided
                // Fixes bug #5509
                try {
                    style[ name ] = value;                                                                        //其次設置style[name]屬性。
                } catch(e) {}
            }

        } else {                                                        //若是未傳入value參數,則讀取內聯樣式。
            // If a hook was provided get the non-computed value from there
            if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {    //優先調用修正對象的get()修正方法,並返回。
                return ret;
            }

            // Otherwise just get the value from the style object
            return style[ name ];                                                                            //沒有修正方法則讀取屬性style[name]。
        }
    },
})

從源碼裏看到咱們能夠每次遞增一些屬性,例如:$("div").css('width','+=20')這樣去累加寬度的,默認單位爲px。工具

對於css的實現以下:

jQuery.extend({
    css: function( elem, name, extra ) {        //負責讀取DOM元素的計算樣式。elem:待讀取的DOM元素,name:待設置的樣式名,extra:一個字符串,用於指示獲取高度、寬度的計算公式。
        var ret, hooks;

        // Make sure that we're working with the right name
        name = jQuery.camelCase( name );            //將樣式名轉換爲駝峯式
        hooks = jQuery.cssHooks[ name ];            //hooks指向駝峯式樣式名對應的修正對象。
        name = jQuery.cssProps[ name ] || name;        //修正駝峯式樣式名,若是origName是float則把name修正爲cssFloat或styleFloat

        // cssFloat needs a special treatment
        if ( name === "cssFloat" ) {                //若是樣式名爲cssFloat
            name = "float";                                //則修正爲float
        }

        // If a hook was provided get the computed value from there
        if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) {    //優先調用修正對象的get()修正方法。
            return ret;

        // Otherwise, if a way to get the computed value exists, use that
        } else if ( curCSS ) {
            return curCSS( elem, name );                //其餘調用curCSS(elem,name)讀取計算樣式。定義在6765行
        }
    },
})

curCSS是jQuery內部定義的一個工具函數,用於獲取某個樣式,實現以下:

curCSS = getComputedStyle || currentStyle;

默認等於getComputedStyle(window.getComputedStyle存在的狀況下,IE及其它瀏覽器),currentStyle是jQuery內部實現的一個另外一個兼容方案,就不討論了,getComputedStyle實現以下:

if ( document.defaultView && document.defaultView.getComputedStyle ) {        //在IE9+和其餘瀏覽器中。若是window.getComputedStyle屬性存在。document.defaultView即window對象。
    getComputedStyle = function( elem, name ) {                                ////定義getComputedStyle()函數
        var ret, defaultView, computedStyle;

        name = name.replace( rupper, "-$1" ).toLowerCase();                        //將可能的駝峯式央視名轉換爲連字符式。rupper = /([A-Z]|^ms)/g,

        if ( (defaultView = elem.ownerDocument.defaultView) &&                    
                (computedStyle = defaultView.getComputedStyle( elem, null )) ) {    //defaultView即window對象    調用window.getComputedStyle()方法獲取該節點的樣式集合
            ret = computedStyle.getPropertyValue( name );                                    //調用getPropertyValue()方法獲取name樣式的值。
            if ( ret === "" && !jQuery.contains( elem.ownerDocument.documentElement, elem ) ) {    //若是沒取到計算樣式,而且當前元素再也不文檔中
                ret = jQuery.style( elem, name );                                    //調用jQuery.style()讀取內聯樣式。
            }
        }

        return ret;
    };
}

經過代碼能夠看到jQuery優先調用window.getComputedStyle()屬性獲取樣式的。

相關文章
相關標籤/搜索