Jquery源碼分析

來源:互聯網
上載者:User

標籤: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

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.