標籤:style c class blog java tar
1、概述
jQuery是一個非常優秀的Js庫,與prototype,YUI,Mootools等眾多的Js類庫相比,它劍走偏鋒,從web開發最實用的角度出發,拋除了一些中看但不實用的東西,為開發人員提供一個短小精悍的類庫。由於其個短小精悍,使用簡單方便,效能相對高效。眾多的開發人員都選擇Jquery來進行輔助的web開發。
在使用jquery時開發,我們也會時常碰到許多的問題,但是jquery的代碼很晦澀,難起看懂,當開發時出現了問題,看不懂源碼,不知道如何去排錯。
John Resig,Jquery的開發人員,寫了兩本書,Pro Javascript Techniques 可以看作是對Jquery的源碼分析。這個對於分析源碼,從基本上去比較目前的類庫都有很大的協助。另外一本是jQuery.in.Action。這本主要是講怎麼去使用Jquery。二本書都深入淺出。還有一個由本手冊由一揪整理編輯JqueryAPI的中文文檔。這三個對於精通Jquery是有很大協助的。
2、init()分析
在分析init()之前,我們得明白jQuery的設計理念。
Jquery是站在開發人員的角度去考慮問題,在使用Js的時候,大部分時間都是對Dom元素進行操作,比如修改元素的屬性,修改內容,修改CSS等。但是取Dom元素的,如getElementsByTag,有可能會取到一些Dom元素的集合,而又正好要這個集合的所有的元素都要進行同樣的操作。如果只有一個元素,完全可以看作只有一個元素的集合。
這樣只要對這個集合進行操作,就會對集合的每個元素都進行操作。jQuery就是基於這個集合而提供了眾多的實用方法,包含了日常開發所需要的功能。對於這個集合,我們稱為jquery對象。
我們可以通過$(params)或jquery(params)來產生Jquery對象。在Jquery文檔中提供了四種方式:jQuery(expression,[context]),jQuery(html),jQuery(elements),jQuery(callback)四種構尋jquery對象的方式。其實Jquery的參數可以是任何的元素,如空參數,都能構成jquery對象。
那麼jquery是如何?的呢?
①②③④⑤⑥⑦⑧⑨⑩
var jQuery = window.jQuery = window.$ = function(selector, context) {
// The jQuery object is actually just the init constructor ‘enhanced‘
return new jQuery.fn.init(selector, context); ①
};
可以看得出其實就是new init(selector, context):
init : function(selector, context) {
selector = selector || document;// 確定selector存在
// 第一種情況 Handle $(DOMElement)單個Dom 元素,忽略上下文
if (selector.nodeType) { ②
this[0] = selector;
this.length = 1;
return this;
}
if (typeof selector == "string") {//selector為string ③
var match = quickExpr.exec(selector);
if (match && (match[1] || !context)) {
if (match[1])// 第二種情況處理$(html) -> $(array) ④
selector = jQuery.clean([match[1]], context);
else {// 第三種情況:HANDLE: $("#id")//處理$("#id")
var elem = document.getElementById(match[3]);
if (elem) {
// IE會返回name=id的元素 ,如果是這樣,就document.find(s)
if (elem.id != match[3]) ⑤
return jQuery().find(selector);
// 構建一個新的jQuery(elem)
return jQuery(elem); ⑥
}
selector = [];
}
} else
// 第四種情況:處理$(expr, [context])==$(content).find(expr)
return jQuery(context).find(selector); ⑦
} else if (jQuery.isFunction(selector)) ⑧ // 第五種情況:處理$(function)七Shortcut for document ready
return jQuery(document)[jQuery.fn.ready ? "ready" : "load"](selector);
// 第六種情況:處理$(elements)
return this.setArray(jQuery.makeArray(selector)); ⑨
},
上面的代碼①可以看出$(xx)或Jquery(xx)得到不是真正的jQuery函數產生的對象,而是jQuery.fn.init函數產生的對象。也是就是jQuery的對象繼承的是jQuery.fn.init的原型。jQuery.fn = jQuery.prototype={..}。我們基本上不用new jQuery(xx),而是直接jQuery(xx),就是採用了new jQuery(xx),先產生jQuery函數的對象,把原型中的繼承下來,返回的也是jQuery.fn.init函數產生的對象。而jQuery函數的對象也拋棄了。可見給jQuery.prototype上增加方法的意義不大。同時也可以看出採用new jQuery(xx)的效率更低。jQuery.fn.init是通過jQuery.fn.init.prototype = jQuery.fn;來獲得的。在擴充jQuery的時候,只要把相關的函數extend到jQuery.fn就可以了。
jQuery.fn.init負責對傳的參數進行分析然後產生jQuery對象。它把第一個參數分成四種情況:
| 類型 |
說明 |
| Dom Element |
第一個參數為Dom元素,第二個參數不用。直接把Dom元素存在新產生的jQuery對象的集合中。返回這個jQuery對象。構建jQuery對象完成。 |
| string |
第一個參數為string有三種情況: 1、html的標籤字串,$(html) -> $(array),第二個參數可選。 執行selector = jQuery.clean([match[1]], context);。該語句是把hteml的字串轉換成dom對象的數組。接著執行Array類型的返回。 2、字串為#id時$(id) 首先通過var elem = document.getElementById(match[3]);取得elem,如沒有取到selector = [];轉到執行Array類型的返回空集合jquery對象。 如找到elem,通過return jQuery(elem);再次產生jquery對象,這次是 Dom Element類型的jquery對象的返回。 3、相容css1-3文法的selector字串,第二個參數是可選的。 執行return jQuery(context).find(selector);。該語句先執行jQuery(context)。可以看出context第二參數可以是任意的值,可以是集合形式。之後就通過find(selector)找到jQuery(context)中所有dom元素都滿足selector運算式的dom元素的集合,構建新的jquery對象,並返回。 #id其實和這種方式是統一的,單獨出來是為了提高效能。 |
| Fn |
第一參數是函數。第二個參數不用。是$(document).ready(fn)的的簡寫,其returnjQuery(document)[jQuery.fn.ready ? "ready" : "load"](selector)是其執行的代碼。這個語句首先執行jQuery(document),它再一次newjQuery.fn.init函數,產生jQuery對象(元素為docume |