解密jQuery內核 樣式操作


基礎回顧

jQuery里節點樣式讀取以及設置都是通過.css()這個方法來實現的,本章通一下分解探究下jquery里這部分代碼的實現

那么jQuery要處理樣式的哪些問題?

先簡單回顧下樣式操作會遇到的問題

HTML樣式定義3種方式了

<link/> 外部引入也就是定義CSS中的
<style/>嵌入式樣式
style特性地定義

給一個HTML元素設置css屬性,如

var head= document.getElementById("head");
head.style.width = "20px";
head.style.height = "10px";
head.style.display = "block";

這是DOM2級樣式提供的API了,這里總的來說還涉及了3個問題,當然也是jQuery內部需要解決的兼容問題了

1 單一的設置太麻煩,而且每次style一次就等於瀏覽器要繪制一次,當然高級的瀏覽器是可能會合並style的次數的

2 style只能針對行類樣式,對於link引入的樣式,無法獲取

3 樣式屬性名的兼容問題,比如駝峰,保留字

 


樣式規則

任何支持style特性的HTML元素在js中有一個對象的style屬性,其實也是一個實例,但是內部屬性命名都是采用的駝峰形式的

比如 background-image =>要寫成  backgroundImage

其中一個是比較特殊的就是 float,  保留字嘛所以就換成 cssFloat,  IE : styleFloat

然后對於width,hight這些處理都最好要有一個量度單位

 


合並cssText

可能針對一種情況給出的處理就是cssText合並

var head= document.getElementById("head");
head.style.cssText="width:20px;height:10px;display:bolck";

和innerHTML一樣,cssText很快捷且所有瀏覽器都支持。此外當批量操作樣式時,cssText只需一次reflow,提高了頁面渲染性能

當然如果是在創建的時候,我們還可以利用文檔碎片

缺點自然就是樣式被整體覆蓋了,所以在處理的時候應該要先獲取需要保留的樣式然后再拼接起來

 


樣式訪問

之前說過了style只能獲取行類樣式了,那么CSS外部樣式表定義的樣式如何處理?

DOM2增加了 document.defauleView,提供了 getComputedStyle()方法 返回了類似style屬性的 css的dom隱射的實例對象

自然包行了樣式表的最終樣式了

getComputedStyle與style的區別

區別就在於getComputedStyle是只能讀的,style是可以可讀可寫的

看看jQuery的

function getStyles( elem ) {
        return window.getComputedStyle( elem, null );
    }

沒有defauleView前綴,查了下在瀏覽器中,該屬性返回當前 document 對象所關聯的 window 對象,如果沒有,會返回 null

應該就能直接window調用了

當然啦,IE這個老大反正就不怎么守規矩了,getComputedStyle方法IE6~8是不支持,所以自己弄出來了currentStyle

處理類似style的處理了,jQuery2X 可以無視IE9以下的兼容了, 所以這個略過~

 

以上就是樣式操作需要了解是基礎了,那么總的來說

jQuery需要的處理問題就顯而易見了

1 參數傳遞

2 命名規范

3 訪問規則

4 性能優化

 


.css()

關於css的接口

jQuery.fn.css 與 jQuery.css

我們知道實例是調用靜態的方法

css的接口參數傳遞是可以很多個組合情況的,這也符合了jQuery少寫多做的原則了

最終方法與設置樣式的方法是實例方法,所以我們看傳遞的參數就知道了,只能是單一的elem, name, value 實參

jQuery.style( elem, name, value ) :
jQuery.css( elem, name );

所以如果我們傳遞是對象或者別的方式就需要一個過濾的環節

css參數的處理也跟之前的attr屬性的處理保持一致,采用了jQuery.access方法統一調配

這個具體之前就分析了,無非就是遞歸參數,但是有個可學的設計思路

分離不同的邏輯判斷通過回調傳遞進去

 


取值jQuery.css()

先看看源碼

css: function( elem, name, extra, styles ) {
            var val, num, hooks,
                origName = jQuery.camelCase( name );
            name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );
            hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
            if ( hooks && "get" in hooks ) {
                val = hooks.get( elem, true, extra );
            }
            if ( val === undefined ) {
                val = curCSS( elem, name, styles );
            }
            if ( val === "normal" && name in cssNormalTransform ) {
                val = cssNormalTransform[ name ];
            }
            if ( extra === "" || extra ) {
                num = parseFloat( val );
                return extra === true || jQuery.isNumeric( num ) ? num || 0 : val;
            }
            return val;
        }

首先自然是檢測是是否駝峰寫法了,如果不是就得轉化下

origName = jQuery.camelCase( name );

把正則拖出來

'background-image'.replace(/-([\da-z])/gi, fcamelCase = function( all, letter ) {
       return letter.toUpperCase();
})

找到-后面的,轉成大寫開頭

 

修正命名float

jQuery.cssProps

 

css樣式的鈎子處理,針對不同的兼容增加的解耦處理,這里先跳過下章再將,不影響代碼流程

image

 

所以最終在默認情況下是通過curCSS處理的取值

curCSS = function( elem, name, _computed ) {
        var width, minWidth, maxWidth,
            computed = _computed || getStyles( elem ),

        // Support: IE9
        // getPropertyValue is only needed for .css('filter') in IE9, see #12537
            ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
            style = elem.style;

最終就是通過getComputedStyle的getPropertyValue方法了,所以通體來說跟之前假設的處理是保持一致的,只是做了不同的兼容

 


設值jQuery.style()

處理的方式與css類似,只是要注意了style才具有樣式的修改權限

這樣的傳對象其實都是需要調用多次style處理的,當然沒有采用cssText的方式處理,因為本身以前的屬性就會丟失了

var color = a.css({"background-color":'red','width':'200px'});

 


總結:

jQuery的處理流程:

1. 分解參數

2. 轉換為駝峰式,修正屬性名

3. 如果有鈎子,則調用鈎子的set get

4. 最終實現都是依靠瀏覽器自己的API的


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM