jQuery 2.0.3 源碼分析 樣式操作


根據API分類

CSS

 


.addClass()

對元素的樣式操作,底層的實現就是修改元素的className值

實現的功能:

增加一條樣式規則: .addClass(‘myClass’)

增加多條樣式規則: .addClass(‘myClass yourClass’)

傳遞回調遍歷樣式規則:

$("ul li:last").addClass(function(index) {
  return "item-" + index;
});

 

從接口傳參去分析這個實現手法:

源碼:

addClass源碼

我把代碼簡略的分了5個步驟

  • 如果傳遞的是回調函數,遞歸調用
  • 分解下樣式規則,通過正則/\S+/g 空白分組
  • 如果元素本身存在class樣式,先取出來
  • 組合成新的規則按照空格分開
  • 通過className 設置新的樣式 

傳遞一個參數與多個參數的處理無非就是字符串的拼接,這里就不詳講,看看代碼就能理解

重點說一下傳遞回調函數的設計

官方給的測試案例

HTML結構

<p class ='selected highlight'>Goodbye</p>
<p class ='selected1 highlight1'>Goodbye</p>
<p class ='selected2 highlight2'>Goodbye</p>

增加樣式代碼

$(p).addClass(function(index,className){
//        index  className
//        0 "selected highlight" 
//        1 "selected1 highlight1" 
//        2 "selected2 highlight2"
    });

遍歷出所有的P節點,並找其對應的class,返回給每一個回調函數

 

看看源碼的設計

//如果傳遞的是回調函數,遞歸調用  ⑴
if ( jQuery.isFunction( value ) ) {
    return this.each(function( j ) {   //each addClass回調 
        jQuery( this ).addClass( value.call( this, j, this.className ) );  
    });
}

不管是寫插件還是其他的,只要是設計操作DOM的在jQuery內部就的到 this.each方法

原因很簡單,jQuery就是一個數組保存着所有對應的節點的下標

image

 

內部在傳遞一個編寫好的回調函數,傳遞給each方法

each方法理解就是一個循環方法,分解出jQuery數組中每一個下標元,然后把每一個元素返回給外部回調

image

 

這里在進步替換下代碼就很明顯了

function(  i, obj[ i ]  ) {   //each addClass回調 
        jQuery( this ).addClass( value.call( this, j, this.className ) );  
 }

這里的this是指向的每一個p元素節點,因為callback.call了一下,把每一個上下文指定到當前的函數了,所以this就是對應的obj[i]

 

最后執行的代碼就是

value.call( this, j, this.className )

value就是最外層用戶定義的回調了

$(p).addClass(function(index,className){
//        index  className
//        0 "selected highlight" 
//        1 "selected1 highlight1" 
//        2 "selected2 highlight2"
    });

 

這里意外的發現jQuery Api沒給出

還包裝了一層jQuery( this ).addClass

那么意味着,jQuery還可以接受用戶最外層的返回參數,然后再調用addClass給當前節點增加新的類名

jQuery( this ).addClass( value.call( this, j, this.className ) );
p.addClass(function(index,className){
        return 'aaaa'
    });

image

 


.removeClass( [className ] )

代碼跟結構與addClass很相似

removeClass源碼

 


.hasClass

.hasClass() 檢測匹配的元素是否指定了傳入的class,只要有一個匹配就返回true

元素可能有多個class,在HTML中多個class用空格隔開;

如果遇到某個元素含有指定的className,.hasClass()將會返回true,即便還指定了其他的className。

/**
* 檢測匹配的元素是否指定了傳入的class,只要有一個匹配就返回true
 * .hasClass( className )
 *   className 要查找的class
* 核心技巧:前后加空格 + indexOf
 */
hasClass: function( selector ) {
    var className = " " + selector + " ", // 前后加空格
        i = 0,
        l = this.length;
    for ( ; i < l; i++ ) {
         // 必須是Element,技巧同樣是前后加空格,同樣是indexOf
        if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) {
            return true;
        }
    }

    return false;
},

 


jQuery.cssHooks

http://www.css88.com/jqapi-1.9/jQuery.cssHooks/

關於jQuery的鈎子,單獨暴露的一個接口,然用戶可以自定義兼容

http://www.cnblogs.com/aaronjs/p/3387906.html 文章已經說了原理

 


.toggleClass()

.toggleClass() 負責對匹配元素集中的每個元素增加或刪除一個或多個class,增加或刪除的行為依賴當前元素是否含有指定的class或switch參數的值

.toggleClass()接受一個或多個class;自從jQuery1.4以后,如果沒有為.toggleClass()指定參數,元素上的所有class名稱將被切換;

自從jQuery1.4以后,className可以是一個函數,函數的返回值作為切換的className。

通過判斷節點上是否有className從而實現切換

結合了hasClass,addClass,removeClass

while ( (className = classNames[ i++ ]) ) {
    // check each className given, space separated list
    if ( self.hasClass( className ) ) {
        self.removeClass( className );
    } else {
        self.addClass( className );
    }
}


免責聲明!

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



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