javascript筆記:臨摹jQuery(一)

來源:互聯網
上載者:User

  多年的軟體開發經驗讓我知道,做技術不管怎麼看都不如做一下,就算是讀源碼,也不應該只是讀,更多還是動手練習,做的時候身臨其境體會大師們設計的巧妙。

  臨摹就是一個很不錯的練習方式,大學讀書時候我的專業是工業設計,大一大二有很多素描色彩課,那時候老師總是布置臨摹的作業,當時自己悟性太低,把臨摹當做抄襲,很少動腦筋去思考臨摹到底是咋回事,現在做軟體了,想臨摹jQuery的架構時候才發現,這是件非常困難的事情,真正的臨摹是要領悟作者的思路,只有理解了作者為什麼這麼做,才知道如何去臨摹作者的作品。

  好了不說這些華而不實的大話了。上篇博文裡我通過學習javascriptRegex,讀了下jQuery裡面選擇造器的代碼,通過傳入到jQuery裡面參數的不同,分析了下jQuery選取器整個代碼的運行,但是如果只是做到這些,上篇文章的福士意義就比較差了,很難讓人理解jQuery到底為什麼會設計選取器,選取器在jQuery裡的地位等等。所以前一篇對jQuery源碼的分析有點斷章取義,所以我今天查閱了一些資料,也靜下心來好好琢磨了下jQuery的架構,根據以前偵錯工具的經驗,我想深入理解jQuery,第一步就是要明白jQuery對象是如何構造的。

  我研究的主要是jquery-1.4.1.js,這是我使用最多的一個版本,而且我經常使用的協助文檔也是這個版本的,另外一個是jquery-1.6.1.js,這個做為1.4.1的配合版本,通過比較二者差異來體會作者在改進jquery的著力點在哪裡,其次我手頭的資料都是用jquery-1.2.x.js作為分析對象。我臨摹時候講jQuery的名稱改為了xQuery,意思是擴充的jQuery,也標示它和原始的jQuery的某些不同(不同是指有時候我會根據代碼的特點,講1.4.1和1.61的代碼進行混搭)。代碼如下:

(注意:我寫的代碼要在裝有firebug的firefox裡面運行)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title> xQuery study</title><script type="text/javascript">(function(window,undefined){var document = window.document,navigator = window.navigator,location = window.location;var xQuery = function(selector,context){return new xQuery.fn.init(selector,context);},// 檢測HTML代碼,ID運算式quickExpr = /^[^<]*(<[\w\W]+>)[^>]*$|^#([\w-]+)$/;xQuery.fn = xQuery.prototype = {constructor:xQuery,init:function(selector,context){var match,elem,ret,doc;//xQuery(''),xQuery(null),or xQuery(undefined);if (!selector){return this;}//xQuery(DOMElement)if (selector.nodeType){this.context = this[0] = selector;this.length = 1;return this;}// body元素在頁面裡面只會有一個,沒必要遍曆DOM進行尋找,這是一個最佳化// 寫法,我是在jquery-1.6.1.js裡面有下面的寫法if (selector === 'body' && !context && document.body){this.context = document;this[0] = document.body;this.selector = selector;this.length = 1;return this;}// 當selector是一個字串的時候if (typeof selector === 'string'){//首先我們要確定我們處理的字串到底是HTML代碼還是ID運算式//在jquery-1.6.1裡面,增加了一個對傳入字串開始結束字元是否都是// <>的判斷,如果是的話就不做Regex的校正了if (selector.charAt(0) === "<" && selector.charAt(selector.length-1) === '>' && selector.length >= 3){match = [ null, selector, null ];//match裡面的值,參見我前一篇博文}else{match = quickExpr.exec( selector );}//quickExpr.exec( selector );運算式執行的結果(詳細解釋參見上一篇博文)//只有當selector字元是帶有#號前置詞字元串或者是字串裡包含有用<>包含的字串時候//match才不可為空,當selector是帶#號的字串時候,match[1]==undefined,而包含有//用<>包含的字串的時候match[1]是不為空白的,因此下面的if...else...就清晰了//注意:我研究的前提都是在context為空白的情況下,因此!context一直都是trueif (match && (match[1] || !context))//當match不為空白,在我研究前提下這個總為true{//這個if就是匹配上了有HTML語句以及有帶#號的字串的情況if (match[1])//HTML語句{//這裡的代碼我現在還沒讀懂,所以不提供代碼,統一返回thisreturn this;}else{//xQuery("#id")的情況//這裡面的代碼取自jquery-1.6.1elem = document.getElementById(match[2]);//下面是針對IE和Opera瀏覽器下的特別處理,因為在這兩個瀏覽器的某些版本裡//document.getElementById有可能用name替代了IDif ( elem && elem.parentNode ){// 在1.4.1裡面是沒有&& elem.parentNode,注釋說這是針對黑莓手機的處理//看來jQuery的觸角已經延伸到了手機領域了,等我研究完javascript就研究//android,那時再瞧瞧這些if ( elem.id !== match[2] ) { //return rootjQuery.find( selector ); //find方法還沒仔細閱讀,因此不提供代碼,統一返回this return this;    }this.length = 1;this[0] = elem;}this.context = document;this.selector = selector;return this;}}else if (!context && /^\w+$/.test( selector )){//這個是xQuery('div'),字串是HTML標籤// 對於HTML標籤是直接使用document.getElementsByTagName,但是這時候並沒有返回jQuery對象// 代碼還會走到if (!context || context.xquery)裡面再進行返回this.selector = selector;this.context = document;selector = document.getElementsByTagName( selector );}else if (!context || context.xquery) {//xQuery('div .red'),xQuery('div')最終也是走到這個裡面再進行return//return (context || rootjQuery).find( selector );//find方法還沒仔細閱讀,因此不提供代碼,統一返回thisreturn this;}else {//這個else是針對這樣的情況xQuery(expr, context),就是context不為空白的情況//return jQuery( context ).find( selector );//find方法還沒仔細閱讀,因此不提供代碼,統一返回thisreturn this;}}//其他代碼省略,主要還沒深入到某些jQuery方法裡面,對某些方法的源碼理解不夠,這邊先不寫了return this;//其他情況統一返回jQuery對象},selector:"",xquery:"1.0",length:0,size:function(){return this.length;}};xQuery.fn.init.prototype = xQuery.fn;window.xQuery = window.$ = xQuery;})(window);function main(){console.log(xQuery(''));console.log(xQuery(null));console.log(xQuery(undefined));console.log(xQuery('').xquery);console.log(xQuery('') instanceof xQuery);console.log(xQuery('#txt01'));console.log(xQuery('#txt01')[0].value);console.log(xQuery(document.getElementById('txt01')));console.log(xQuery(document.getElementById('txt01'))[0].value);}//window.onload = main();//error</script></head><body><form><input type="text" id="txt01" name="txt01" value="Test xQuery"/><input type="button" value="BTN" onclick="main()"/></form></body></html>
 結果如下:

另外我用jQuery實現同樣的功能,代碼如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>jQuery Test</title></head><body><form><input type="text" id="txt01" name="txt01" value="Test xQuery"/><input type="button" value="BTN" onclick="main()"/></form></body></html><script src="jquery-1.4.1.js"></script><script type="text/javascript">function main(){console.log(jQuery(''));console.log(jQuery(null));console.log(jQuery(undefined));console.log(jQuery('').jquery);console.log(jQuery('') instanceof jQuery);console.log(jQuery('#txt01'));console.log(jQuery('#txt01')[0].value);console.log(jQuery(document.getElementById('txt01')));console.log(jQuery(document.getElementById('txt01'))[0].value);}</script>
結果如下:

呵呵,能列印出具體值的結果是差不多的。

我臨摹的架構還不完善,但我自己覺得大致有jQuery的雛形了,現在滿足的功能也比較有限,只有jQuery裡面參數為jQuery(''),jQuery(null),jQuery(undefined),jQuery('#txt01'),jQuery(document.getElementById('txt01'))這些功能還是按照jQuery代碼實現了,其他的參數因為這些代碼還沒有閱讀,先不給出來,另外xQuery對象的也構建的不全,這些以後也會補充進去。不過上面的代碼用javascript基礎知識來分析,就能研究出很多有趣的特性,下面的幾篇博文會圍繞我這個不完善的代碼進行詳盡分析。分析完後,我接下逐步完善xQuery,讓他和jQuery長得一模一樣。
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.