jQuery核心源碼解讀

上傳人:文*** 文檔編號(hào):62310898 上傳時(shí)間:2022-03-14 格式:DOC 頁數(shù):13 大?。?14KB
收藏 版權(quán)申訴 舉報(bào) 下載
jQuery核心源碼解讀_第1頁
第1頁 / 共13頁
jQuery核心源碼解讀_第2頁
第2頁 / 共13頁
jQuery核心源碼解讀_第3頁
第3頁 / 共13頁

下載文檔到電腦,查找使用更方便

0 積分

下載資源

還剩頁未讀,繼續(xù)閱讀

資源描述:

《jQuery核心源碼解讀》由會(huì)員分享,可在線閱讀,更多相關(guān)《jQuery核心源碼解讀(13頁珍藏版)》請(qǐng)?jiān)谘b配圖網(wǎng)上搜索。

1、文檔供參考,可復(fù)制、編制,期待您的好評(píng)與關(guān)注! 總體架構(gòu) jQuery是個(gè)出色的javascript庫,最近結(jié)合它寫javascript,看了下源碼。 先從整體、全局的看,jQuery的源碼幾乎都在下面的代碼中: (function() { //…… })(); 第一個(gè)括號(hào)里面是個(gè)匿名函數(shù),第二個(gè)括號(hào)表示馬上執(zhí)行第一個(gè)括號(hào)里面的代碼。 首先明白,javascript里面是沒有命名空間的,要保證你的javascript函數(shù)、對(duì)象與其他的不沖突,這里用了javascript的一個(gè)技巧:你的所有javascript函數(shù)、對(duì)象都在一個(gè)匿名函數(shù)里面定義,確保了所定義

2、的函數(shù)、對(duì)象的有效范圍,起到了命名空間的作用。既然作用范圍在這個(gè)匿名函數(shù)中,怎么被別人使用呢?下面看它的下面代碼: var jQuery = window.jQuery = function(selector, context) { //…… }; 這里讓jQuery庫中最重要的對(duì)象jQuery成為了window對(duì)象的一個(gè)屬性,這樣就可以在其他地方像使用document(document也是window的一個(gè)屬性)一樣使用jQuery了。也許使用過jQuery的朋友驚訝-我沒有使用jQuery對(duì)象,一直使用$的。沒錯(cuò),那是jQuery的同名對(duì)象: window.$ = jQuery;

3、 現(xiàn)在明白了吧。 執(zhí)行過程分析 JavaScript是一門基于對(duì)象的語言,而它的對(duì)象技術(shù)的實(shí)現(xiàn)又和其他語言有著很大的差異,在JavaScript中,一個(gè)類的定義一般采用下面這種模式(我所看到的): // 定義一個(gè)構(gòu)造函數(shù); testClass(param1, param2) { ??this.attr1 = param1; ??this.attr2 = param2; ?? ... } // 在prototype對(duì)象上擴(kuò)展,加上相應(yīng)的方法; testClass.prototype = { ?? Method1: function() {...}, ?

4、? Method2: function() {...}, ?? ... } // 定義一個(gè)實(shí)例; var test = new testClass();   在jQuery.js中,同樣也是這種模式,只不過它要復(fù)雜很多,而且它還定義了一個(gè)jQuery.extend()的靜態(tài)方法來擴(kuò)展類的功能,jQuery.js代碼執(zhí)行過程完整分析如下: // 防止多次載入而進(jìn)行jQuery對(duì)象的判斷; if ( typeof window.jQuery == "undefined" ) { ?? window.undefined = window.undefined; ??// jQ

5、uery的構(gòu)造函數(shù); ??var jQuery = function( a, c ) { ... }; ??// jQuery的命名空間$; ??if ( typeof $ != "undefined" ) jQuery._$ = $; ??var $ = jQuery; ??// 給jQuery的prototype增加一些基礎(chǔ)方法和屬性; ??// 其中有些方法是調(diào)用下面的擴(kuò)展方法實(shí)現(xiàn)的; ??// 注意下面的jQuery.fn = jQuery.prototype; ?? jQuery.fn = jQuery.prototype = { ???? each: fu

6、nction( fn, args ) { ... }, ???? find: function( t ) { ... }, ???? ... ?? }; ??// jQuery實(shí)現(xiàn)繼承的方法; ?? jQuery.extend = jQuery.fn.extend = function( obj, prop ) {...}; ??// 實(shí)現(xiàn)一些基礎(chǔ)的函數(shù),有大部分是上面調(diào)用; ?? jQuery.extend({ ???? init: function() { ... }, ???? each: function( obj, fn, args ) { ... },

7、???? find: function( t, context ) { ... }, ???? ... ?? }); ??// 瀏覽器版本的檢測; ??new function() { ???? jQuery.browser = { safari:..., opera:..., msie:..., mozilla:... }; ???? ... ?? }; ??// jQuery.macros擴(kuò)展,主要用于jQuery.init(),進(jìn)行jQuery的初始化; ?? jQuery.macros = { ???? filter: [ ... ], ???? attr

8、: { ... }, ???? each: { ... }, ???? ... ?? }; ??// jQuery初始化; ?? jQuery.init(); ??// 實(shí)現(xiàn)jQuery的重要方法ready(); ?? jQuery.fn.extend({ ???? ready: function( f ) { ... } ???? ... ?? }; ??// 上面ready()方法的具體實(shí)現(xiàn); ?? jQuery.extend({ ???? ready: function() { ... }, ???? ... ?? }; ??// 對(duì)瀏覽器

9、某些事件進(jìn)行綁定和解綁定; ??new function() { ???? ... ???? jQuery.event.add( window, "load", jQuery.ready ); ?? }; ??// 當(dāng)IE瀏覽器關(guān)閉時(shí),清除上面綁定的事件,防止內(nèi)存泄漏; ??if ( jQuery.browser.msie ) jQuery(window).unload( ... ); ??// 實(shí)現(xiàn)一些瀏覽器效果; ?? jQuery.fn.extend({ ???? show: function( speed, callback ) { ... }, ????

10、hide: function( speed, callback ) { ... }, ???? ... ?? }; ??// 上面的一些函數(shù)具體實(shí)現(xiàn); ?? jQuery.extend( {...} ); ??// 以下都是Ajax的實(shí)現(xiàn),這里聲明原型,具體實(shí)現(xiàn)調(diào)用下面的函數(shù); ?? jQuery.fn.extend({ ???? loadIfModified: function(url, params, callback ) { ... }, ???? ... ?? }; ??// 針對(duì)IE瀏覽器創(chuàng)建不同的XMLHttpRequest對(duì)象; ??if (jQ

11、uery.browser.msie && typeof XMLHttpRequest == "undefined") { ... }; ??// Ajax函數(shù)的綁定; ??new function() { ????var e = "ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess".split(","); ???? ... ?? }; ??// Ajax函數(shù)的具體實(shí)現(xiàn); ?? jQuery.extend({ ???? get: function( url, data, callback, type, ifModi

12、fied ) { ... }, ???? post: function( url, data, callback, type ) { ... }, ???? ajax: function( type, url, data, ret, ifModified ) { ... }, ???? ... ?? } } 構(gòu)造函數(shù)詳解 在jQuery.js的構(gòu)造函數(shù)中,充分利用了JavsScript語言的動(dòng)態(tài)性——對(duì)行參的類型和個(gè)數(shù)沒有的嚴(yán)格要求,以至于一個(gè)函數(shù)可以實(shí)現(xiàn)多種功能需求,也為JavaScript語言的多態(tài)性提供了基礎(chǔ),在這個(gè)構(gòu)造函數(shù)中,提供了六種不同的調(diào)用格式(根據(jù)官方

13、API文檔),具體如下($ = jQuery):   1、$(String expr):根據(jù)給定的CSS選擇符查找匹配的元素,如$("div>p");   2、$(Element elem):將給定的DOM元素對(duì)象轉(zhuǎn)換為jQuery對(duì)象,如$(document).find("div>p");   3、$(Array elems):如$(myForm.elements).hide();   4、$(Function fn):是$(document).ready()的簡寫模式,如:$( function fn(){ ... } );   5、$(jQuery obj)

14、:如:var div = $("div");?? $(div).find("p");   6、$(String expr, Element context):在context中查找expr,如:$("div", xml.responseXML);   另外,jQuery中提到了Chainable Methods的思想,也就是調(diào)用jQuery中的方法會(huì)返回一個(gè)jQuery對(duì)象,仍然可以繼續(xù)調(diào)用其中的方法,這樣,就形成了一個(gè)“鏈條”,通過“.”一個(gè)一個(gè)調(diào)用下去,這個(gè)在構(gòu)造函數(shù)中有具體體現(xiàn),其中有如下一條語句:   if( window == this ) return new jQuery(

15、 a, c );   這個(gè)就是為了返回一個(gè)jQuery對(duì)象,在首次調(diào)用jQuery( a, c )函數(shù)時(shí),this是等于window的,所以每次都會(huì)創(chuàng)建一個(gè)jQuery對(duì)象,更詳細(xì)的代碼分析見下: // jQuery的構(gòu)造函數(shù); var jQuery = function( a, c ) { ????// $(document).ready()的簡寫形式,只有在$(function(){})下才會(huì)執(zhí)行; ????if ( a && typeof a == "function" && jQuery.fn.ready ) return jQuery(document).ready(a);

16、 ????// 確保參數(shù)a非空,默認(rèn)值為document; ????? a = a || jQuery.context || document; ????// 如果參數(shù)a是jQuery對(duì)象(a.jquery="1.0.3"),則克隆一個(gè)與a相同的jQuery對(duì)象; ????if ( a.jquery ) return jQuery( jQuery.merge( a, [] ) ); ????// 從給定的參數(shù)c(要求c必須是jQuery對(duì)象)中查找a; ????if ( c && c.jquery ) return jQuery( c ).find( a ); ?

17、???// 如果是初次調(diào)用$(),因?yàn)樵趙indow環(huán)境下,所以創(chuàng)建一個(gè)新的jQuery對(duì)象,如果去掉new則循環(huán)執(zhí)行; ????if ( window == this ) return new jQuery(a,c); ????// 分析HTML串,如“div

    p”; ????if ( a.constructor == String ) { ????????var m = /^[^<]*(<.+>)[^>]*$/.exec( a ); ????????if ( m ) a = jQuery.clean( [ m[ 1 ] ] ); ????? } ????// 如

    18、果參數(shù)a是元素?cái)?shù)組,則要執(zhí)行jQery.merge(),否則要執(zhí)行jQuery.find(); ????this.get( a.constructor == Array || a.length && !a.nodeType && a[0] != undefined && a[0].nodeType ???????????// 處理元素?cái)?shù)組; ????????????? jQuery.merge( a, [] ) ????????? :??// 查找相匹配的元素并保存; ????????????? jQuery.find( a, c ) ); ????// 如果附加了另外的函數(shù),

    19、則在每個(gè)相匹配的jQuery對(duì)象上執(zhí)行這個(gè)函數(shù); ????var fn = arguments[ arguments.length - 1 ]; ????if ( fn && typeof fn == "function" ) this.each( fn ); ????return this; }; //jQuery的結(jié)束; 插件擴(kuò)展機(jī)制 從零開始寫jQuery框架 摘要: 本文由簡到繁地介紹了以jQuery作為藍(lán)本的js框架開發(fā)步聚, 希望借助本文大家對(duì)jQuery這樣的框架內(nèi)部有一個(gè)大致

    28、的認(rèn)識(shí)。 隨著時(shí)代發(fā)展,javascript陣營里面出現(xiàn)了越來越多的優(yōu)秀的框架,大大簡化了我們的開發(fā)工作,在我們使用這些框架的時(shí)候是不是也應(yīng)該飲水思源想想它們都是怎樣構(gòu)建起來的呢?如果你不滿足于僅僅是使用一些現(xiàn)成的API,而是深入了解它們內(nèi)部的實(shí)現(xiàn)機(jī)制(照某人的說法, API是貶值最快的東西),最好的辦法就是閱讀它們的源代碼了,前提是你讀得懂。 最近兩天研究了一下jQuery的源碼,在這里將本人一些粗淺認(rèn)識(shí)分享出來,不當(dāng)之處請(qǐng)各位指正。好了,下面我們就來看看jQuery大概是怎樣工作的,我假定你已經(jīng)具備了一些基本的javascript知識(shí),如果基礎(chǔ)不夠俺推薦你閱讀《JavaScri

    29、pt高級(jí)程序設(shè)計(jì)》和《悟透JavaScript》這兩本書。本文不適合對(duì)js里面的類、對(duì)象、函數(shù)、prototype等概念沒有了解的朋友。 我們從最開始的說起: 首先構(gòu)造一個(gè)對(duì)象給使用者,假定我們這個(gè)框架叫 Shaka? ?( 俺的名字;) ) var Shaka = function(){}; 這里我們創(chuàng)建了一個(gè)空函數(shù),里面什么也沒有,這個(gè)函數(shù)實(shí)際上就是我們的構(gòu)造函數(shù)。為了讓我們生成的對(duì)象能夠調(diào)用在prototype里定義出來的方法, 我們需要用原型的方式(把Shaka當(dāng)作是一個(gè)類)給Shaka添加一些方法,于是定義:: Shaka.fn =??Shaka.prototype =

    30、{}; 這里的Shaka.fn相當(dāng)于Shaka.prototype的別名,方便以后使用,它們指向同一個(gè)引用。 OK,我們添加一個(gè)sayHello的方法, 給Shaka添加一個(gè)參數(shù),這樣這個(gè)框架最基本的樣子已經(jīng)有了,如果它有生命的話那么它現(xiàn)在是1歲, 看代碼: Error! Reference source not found. ?提示:您可以先修改部分代碼再運(yùn)行 好啦,先別激動(dòng), 我們注意到這個(gè)框架跟jQuery在使用上是有一些差別的, 比如在jq 中我們可以這樣寫 jQuery('#myid').someMethod(); 這是怎樣做到的呢, 也就是說 jQuery()這個(gè)構(gòu)造

    31、函數(shù)返回了一個(gè)jQuery的對(duì)象實(shí)例,因此我們可以在上面調(diào)用它的方法,所以Shaka的構(gòu)造函數(shù)應(yīng)該返回一個(gè)實(shí)例,它看起來應(yīng)該是這個(gè)樣子: var Shaka = function(){ return //返回Shaka的實(shí)例; }; 那么我們要如何取得一個(gè)Shaka的實(shí)例呢, 我們先來回顧一下使用prototype方式來模擬類的時(shí)候 var someObj = new??MyClass(); 這個(gè)時(shí)候?qū)嶋H上是創(chuàng)建一個(gè)新對(duì)象someObje,把新對(duì)象作為this指針,調(diào)用 MyClass函數(shù),即類的構(gòu)造函數(shù), 然后 someObj 就獲得了在 MyClass.prototype里面定義的方法,

    32、 這些方法內(nèi)的this指針指當(dāng)前對(duì)象實(shí)例。 在jQuery中使用了一個(gè)工廠方法來創(chuàng)建一個(gè)實(shí)例,這個(gè)方法位于jQuery.prototype中, 現(xiàn)在我們重新來定義Shaka.prototype, 給它添加一個(gè)init方法用于返回一個(gè)Shaka的實(shí)例, 并且把Shaka的構(gòu)造函數(shù)稍稍改變一下: var Shaka = function(age) { return new Shaka.fn.init(age); }; Shaka.fn = Shaka.prototype = { ? ? ? ?init: function(age) { this.age = age; retu

    33、rn this; }, ? ? ? ?sayHello: function() { alert('I am a little baby, my age is ' + this.age + ' years old.'); } }; Shaka.fn.init.prototype = Shaka.fn;//這里new Shaka.fn.init(age)創(chuàng)建的對(duì)象具有init方法的prototype指向?qū)ο蟮姆椒?, 因此我們將init方法的prototype指向 Shaka的prototype, 這樣創(chuàng)建出來的對(duì)象就具有了Shaka.prototype里面定義的方法。 OK,現(xiàn)在

    34、我們的小寶寶變成大一點(diǎn)的寶寶了,打個(gè)招呼先: Error! Reference source not found. ?提示:您可以先修改部分代碼再運(yùn)行 嗯,好象有點(diǎn)樣子了,但是光這樣還不行,來點(diǎn)實(shí)際的, 我們?cè)谛驴蚣苤袑?shí)現(xiàn)jquery里val()方法的部分功能,這個(gè)方法不加參數(shù)調(diào)用時(shí)返回指定ID的input的值,加參數(shù)時(shí)為設(shè)定這個(gè)input的值,與jQery一樣,我們約定使用id來查找對(duì)象時(shí)使用"#"符號(hào)。把要查找的目標(biāo)ID作為構(gòu)造函數(shù)的參數(shù)傳進(jìn)去,我們給Shaka.prototype添加一個(gè)val()方法, 給Shaka添加一個(gè)selector的屬性用于存儲(chǔ)我們要查找的目標(biāo)。: Sh

    35、aka.fn = Shaka.prototype = { ? ? ? ?init: function(selector) { this.selector = selector; return this; }, ? ? ? ?val: function(newValue) { //方法實(shí)現(xiàn)代碼 } }; var Shaka = function(selector) { return new Shaka.fn.init(selector); }; ?提示:您可以先修改部分代碼再運(yùn)行 到目前為止我們已經(jīng)創(chuàng)建一個(gè)可以工作的框架雛形,為了使程序可以更方便地被調(diào)用,比如jQu

    36、ery可以使用$符號(hào)來簡寫,我們也弄一個(gè),在此之前我們先來回顧兩個(gè)東西: 1. 我們?cè)谀_本中可以這樣定義變量: var foo = 'someThing'; bar = 'otherthing'; 這樣兩種寫法都是合法的,但是意義完全不同, 第一個(gè)語句創(chuàng)建了一個(gè)新的變量,而第二個(gè)是定義了window對(duì)象的一個(gè)屬性,相當(dāng)于window.bar = 'otherthing';, 因此我們想使我們的Shaka具有這樣的調(diào)用方式能力: $.someMethod();就需要將Shaka設(shè)置為window的一個(gè)屬性, 于是我們的Shaka構(gòu)造函數(shù)就得寫成這樣: var Shaka = wi

    37、ndow.Shaka = window.$ = function(selector) { return new Shaka.fn.init(selector); }; 2. javascript的匿名函數(shù). 創(chuàng)建并執(zhí)行一個(gè)匿名函數(shù)的基本形式: (function(){ alert('Hello World!'); })(); 為什么要用到匿名函數(shù)呢,因?yàn)槲覀儾幌氚裇haka的內(nèi)部實(shí)現(xiàn)暴露出來,這樣容易與其它代碼沖突,只提供一個(gè)單一的入口,我們可以這樣測試一下: Error! Reference source not found. ?提示:您可以先修改部分代碼再運(yùn)行 然后,還有一個(gè)

    38、問題需要解決,俺們的框架做出來了但是還很簡陋,在這之前我們需要讓它與其它的框架協(xié)同工作,因此帶來一個(gè)問題, 如果我們都使用$作為簡寫形式就會(huì)沖突了, 象jQuery一樣,我們需要提供一個(gè)noConfilit的方法“出讓”$的使用權(quán)。在我們的程序最開始處加入下面的代碼: var _$ = window.$; 意思是將此前定義的$對(duì)象引用放到 _$ 中, 然后我們?cè)俳oShaka擴(kuò)展一個(gè)方法出來, 如果其它開發(fā)者需要自行擴(kuò)展的話也可以使用這個(gè)方式(jQuery的extend方法提供了更為強(qiáng)大的功能,請(qǐng)大家自行研究): (function($){ //extend method definiti

    39、on. })(Shaka); 意思是將Shaka作為這個(gè)匿名函數(shù)的參數(shù)來調(diào)用這個(gè)方法。 前面我們講過 Shaka.fn 就是 Shaka.prototype 的別名,因此我們要在Shaka.prototype 里面添加新的方法就可以寫成這樣 (function($){ ? ? ? ?$.fn.noConflict = function(){ ? ? ? ?? ? ? ?window.$ = _$;//把$還給在開始處取得的引用. ? ? ? ?}; })(Shaka); 現(xiàn)在我們來看一個(gè)完整的: Error! Reference source not found. 13 / 13

展開閱讀全文
溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

相關(guān)資源

更多
正為您匹配相似的精品文檔

相關(guān)搜索

關(guān)于我們 - 網(wǎng)站聲明 - 網(wǎng)站地圖 - 資源地圖 - 友情鏈接 - 網(wǎng)站客服 - 聯(lián)系我們

copyright@ 2023-2025  zhuangpeitu.com 裝配圖網(wǎng)版權(quán)所有   聯(lián)系電話:18123376007

備案號(hào):ICP2024067431號(hào)-1 川公網(wǎng)安備51140202000466號(hào)


本站為文檔C2C交易模式,即用戶上傳的文檔直接被用戶下載,本站只是中間服務(wù)平臺(tái),本站所有文檔下載所得的收益歸上傳人(含作者)所有。裝配圖網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)上載內(nèi)容本身不做任何修改或編輯。若文檔所含內(nèi)容侵犯了您的版權(quán)或隱私,請(qǐng)立即通知裝配圖網(wǎng),我們立即給予刪除!