首頁  >  文章  >  web前端  >  jQuery源碼解讀之addClass()方法分析_jquery

jQuery源碼解讀之addClass()方法分析_jquery

WBOY
WBOY原創
2016-05-16 16:13:281452瀏覽

本文較為詳細的分析了jQuery源碼解讀之addClass()方法。分享給大家供大家參考。具體分析如下:

給jQuery原型物件擴充addClass功能,jQuery.fn就是jQuery.prototype

複製程式碼 程式碼如下:
jQuery.fn.extend({
/*
可以看出這是一個函數稱為addClass的插件方法。
*/
    addClass: function( value ) {
        var classes, elem, cur, clazz, j, finalValue,
            i = 0,
/*
this表示選擇器選擇的準備添加class的jQuery對象,len是該jQuery對象數組的長度。
*/
            len = this.length,
//在有一個操作數不是布林值的情況下,&&操作就不一定會傳回布林值,此時,它遵循下列規則:
//1.如果第一個操作數不是布林類型,則傳回第二個操作數;
//2.如果第二個操作數不是布林類型,則只有在第一個操作數的求值結果為true,的情況下才會傳回該物件;
//3.如果兩個操作數都不是布林類型,則傳回第二個操作數;
//4.如果有一個運算元是null,則回傳null;
//5.如果有一個操作數是NaN,則回傳NaN;
//6.如果有一個運算元是undefined,則回傳undefined 。
//情況1:如果value是null,符合規則4,回傳null,即proceed值為null;
//情況2:如果value是undefine,符合規則6,回傳undefined,即proceed值為undefined;
//情況3:如果value是NaN,符合規則5,則回傳NaN,即proceed值為NaN;
//情況4:如果value是數字類型,回傳false;
//情況5:如果value是布林型別,回傳false;
//情況7:如果value是Array,Object,Function類型,符合規則2,但typeof value === 'string'是false,所以返回該對象,則回傳false。
//情況8:如果value是字串類型,符合規則2,則回傳value。
//因此,這句話只能判斷value是不是字串型,並且傳回這個字串賦值給proceed。其他任何類型最後都會回傳false,或是可被隱式轉換為false的類型。
            proceed = typeof value === "string" && value;
//由於上面只能判斷是否是字串類型,下面這句話是判斷value是否為Function類型。使用了jQuery的全域函數isFunction判斷,就是$.isFunction()。
        if ( jQuery.isFunction( value ) ) {
//如果value是Function類型,就進到這裡了。
//回傳jQuery對象,為了鍊式呼叫。
//這裡的this是你選擇器選擇的jQuery物件。
            return this.each(function( j ) {
//開始迭代,這裡的this可不是jQuery物件了,是目前迭代的DOM對象,所以用jQuery(this)包裝了一下,成為一個jQuery對象,這樣就可以使用jQuery方法。 j表示每次遍歷的索引。傳遞一個用來設定類別名稱的有回傳值的value函數。 value這個函數每次call當前DOM為其執行對象,並傳入當前DOM索引值和類別名,value函數返回的值,由jQuery(this).addClass(返回值)再次呼叫addClass()方法。如果傳回的是字串,就執行另外一個if的分支。如果回傳的還是function,則繼續呼叫傳回的這個function。
                jQuery( this ).addClass( value.call( this, j, this.className ) );
            });
        }
//之前得到proceed是字串,這裡判斷下是否為空字串,非空字串隱式轉換為true。空字串隱式轉換成false哦,那麼if語句區塊就不再執行了,程式跳到最後的return this,回傳這個jQuery物件就執行完了。
        if ( proceed ) {
//proceed非空字串,開始執行if語句區塊。假定value是"show bd1"。
//rnotwhite是正規表示式(/S /g),意思是全域匹配非空白字元一次或更多次。
//(value || "")回傳"show bd1",很簡單。
//"show bd1".match((/S /g)) || []返回["show", "bd1"],match不知道什麼作用的同學快去查查吧。
            classes = ( value || "" ).match( rnotwhite ) || [];
//現在classes是['show', 'bd1']一個你要加入類別名稱的陣列。
//下面開始遍歷,為每個DOM物件新增類別。
            for ( ; i //this是jQuery對象,elem是當前DOM對象。
                elem = this[ i ];
/*
===運算子比&&運算子優先權高,先判斷DOM節點型別是否為元素節點。
rclass是正規表示式/[trnf]/g;
括號內的三目運算子表示,當前DOM節點是否已經有class,有的話,則將class中可能存在的製表符,換行符,回車符等替換為帶有一個空格的字串" " ,並且在當前class的前後各加一個空格;如果當前DOM節點還沒有class,則也是給一個帶一個空格的字串" "。最後變成
cur = elem.nodeType === 1 && "show bd1",這很熟悉啊,沒錯,依照最開始的那6個規則求值。
假設elem的節點型別是1,則 cur = true && " ",最後cur = "show bd1"。
如果elem的節點類型不是1,那麼 cur = false && " ",最後cur = false。
*/
                cur = elem.nodeType === 1 && ( elem.className ?
                    ( " " elem.className " " ).replace( rclass, " " ):" ");
//現在cur = " show bd1 ",進入if語句區塊執行。
                if ( cur ) {
                    j = 0;
/*
classes為["show bd1"]
循環檢查要新增的類別是否已經存在與目前DOM元素已經有的類別裡。
如果沒有,則添加這個類別。
*/
                    while ( (clazz = classes[j ]) ) {
                        if ( cur.indexOf( " " clazz " " )                             cur = clazz " ";
                        }
                    }
/*
最後用$.trim()將類別" show bd1 "兩頭的空格字元去掉。
檢查目前DOM元素的類別是否和拼接好的類別重複。避免不必要的重複添加相同類別的渲染。
*/
                    finalValue = jQuery.trim( cur );
                    if ( elem.className !== finalValue ) {
                        elem.className = finalValue;
                    }
                }
            }
        }
//回傳這個jQuery對象,為了以後的鍊式呼叫。

        return this;
    }
});

希望本文所述對大家的jQuery程式設計有所幫助。

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn