DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> JavaScript入門知識 >> jQuery入門知識 >> JQuery特效代碼 >> jQuery 源碼分析筆記(2) 變量列表
jQuery 源碼分析筆記(2) 變量列表
編輯:JQuery特效代碼     
_jQuery = window.jQuery;
_$ = window.$;
這兩個變量是jQuery唯一使用的兩個全局變量。在jQuery.noConflict()函數中,會把這兩個變量恢復回去。
對於浏覽器檢測,jQuery使用的是檢查UserAgent,而沒有使用特性檢測。
rwebkit = /(webkit)[ \/]([\w.]+)/,
ropera = /(opear)(?:.*version)?[ \/](\w+)/,
rmsie = /(msie) ([\w.]+)/,
rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/,
初始化函數init
jQuery對JS對象的處理比較繞,而最終目的就是把jQuery選擇器得到的結果變成和數組差不多的一個對象。有length,first,last等。因為$("...")就是從DOM樹從選擇一些節點出來。但是,$還有很多其他功能,比如常用的$(function() { ... })用來頁面加載後初始化執行,$("<..>...</...>")來直接得到一個節點,用來append到DOM樹中。
接下來從93行開始就是很長的一段init函數。Init: function(selector, context, rootjQuery)
步驟:
1、Selector是非法參數:空字符,null和undefined則直接返回this。即有默認屬性的jQuery對象。
2、Selector是DOMElement。即用原生的JS,比如getElementById等得到的元素。那麼,相當於把原生的DOM對象用$包裝一次。把這個元素放到內部數組的第一個位置,並把length設置為1。然後返回。
3、特殊優化處理$("body")。即document.body元素。
4、Selector是以<開頭,以>結尾的字符串。那麼假定是想用字符串新建一個DOM元素。比如$("<a href='http://www.cnblogs.com">博客園</a>")。為了安全起見,這裡使用了一個正則表達式來檢查,到底是<...>...</...>形式還是#id的形式。
quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/。在quickExpr.exec(selector)後,如果是HTML字符串,那麼會得到[match, match, undefined],而#id形式會得到[#id, undefined, id]的結果。這樣就把字符串區別開了。
對於HTML字符串,如果只有一個tag,那麼直接調用createElement。否則調用一個createFragment輔助函數,這個函數使用createDocumentFragment,然後把所有tag都插進去。
createFragment實現在5892行,這裡有一個值得注意的地方就是jQuery對於HTML片段做了緩存處理。而且對於不同的浏覽器和元素有不同的處理,作者寫了大段的注釋說明。歸納起來就是(1)只緩存小於0.5KB的小片段。(2)selected狀態不緩存。(3)IE6的<object>和<embed>元素不緩存。(4)WebKit不緩存元素的checked屬性。以上這些不緩存的原因是jQuery使用克隆(Clone)節點的方式進行緩存,而2-4提到的情況在Clone時會丟失。jQuery使用了正則,或者jQuery.support輔助函數來進行是否緩存的策略判斷。這裡先略過。jQuery.support牽扯很多浏覽器相關問題。
5、如果在4中檢查到是#id,則直接調用document.getElementById
6、如果selector是function,則把這個函數當作是document.ready的事件處理函數
7、剩余的各種情況,比如傳入了context等。統一調用一個find(selector)來處理。這個函數以後再議。(5109行,jQuery.find = Sizzle; jQuery.expr = Sizzle.selectors; 表明,其他復雜的selector表達式都扔給Sizzle項目了)
jQuery基本成員
jQuery被設計成一個行為和數組很像的對象。所以需要一些轉換方法和基本屬性。
1、jquery:版本號。最簡單的得到版本號的方式:$().jquery
2、length和size():長度。
3、toArray():轉換成JS數組
4、get(num):返回第N個元素。如果傳入null,則直接返回toArray()的結果。這裡返回的就是DOMElement了。
5、pushStack():參見http://api.jquery.com/pushStack/ 。內部new了一個新的jQuery對象,然後把elems和selector得到的結果合並進去,然後返回這個新的jQuery對象。這裡有個prevObject屬性的設置,往下看end()函數。
6、each(callback, args):遍歷數組內的元素。內部調用了$.each Utiltiy。
7、ready(fn):其實和$(function() { })是等價的。
8、eq(i):i允許正負數字,而且返回的仍然是jQuery對象,只不過只有一個元素了。其實只是slice的包裝。
9、first()和last():其實就是eq(0)和eq(-1),很簡單的一個包裝。
10、slice():根據參數獲得數組一部分的引用。內部使用pushStack實現的。所以返回的也是一個新的jQuery對象。
11、map(callback):對每個元素依次調用callback。把原來的元素A的數組映射為元素B的數組。callback就是元素A->元素B的映射函數。函數式編程(FP)裡很基礎的一個概念。
12、end(): 參見http://api.jquery.com/end 。這個是返回選擇器的上一個狀態。返回的是jQuery.prevObject屬性。這個屬性是在pushStack函數裡面設置的,它在返回新的jQuery對象之前,把這個新對象的prevObject設置為this。這樣多次pushStack之後就變成了一個鏈表(chain)。而end()就是沿著鏈表往前走一個節點。經過了selector之後,根的prevObject是document。比如$("body div").prevObject就是Document。
extend函數
在jQuery基本成員之後,所有其他成員都是用extend加上去的。聲明:
jQuery.extend = jQuery.fn.extend = function() { }
把target後面的所有object參數的屬性全部賦值到target上,如果第一個參數是boolean值,則用來指定是否深拷貝。然後返回修改過的target(不是新對象,extend函數直接修改原對象)。
XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved