jQuery核心詳解與實踐讀書筆記2:破解jQuery選取器介面1

來源:互聯網
上載者:User

jQuery核心詳解與實踐讀書筆記2:破解jQuery選取器介面1
前兩篇已經介紹了如何搭建一個jQuery架構的雛形,從這一篇開始詳細瞭解jQuery選取器的介面。jQuery選取器功能強大但用法很簡單,它僅僅提供了一個介面:jQuery(),也可以簡寫為$()。 1. 簡單但很複雜的黑洞 jQuery提供了唯一的介面(jQuery()或$())使選取器與外界進行交流。jQuery架構的基礎是查詢,即查詢文件項目對象,因此可以認為jQuery對象就是一個選取器,並在此基礎上構建和執行查詢過濾器。jQuery查詢結果的資料集合是jQuery對象的一部分。在$()函數中可以包含選擇字串,HTML字串,DOM對象和資料集合等不同類型的參數。jQuery是如何分辨這些參數呢?為了方便理解其中的奧秘,把jQuery架構進行簡化,先刪除所有方法,函數以及邏輯代碼,然後在init()構造器中,使用alert()方法擷取selector參數的類型和資訊,代碼如下: 複製代碼 1 (function() { 2   var window = this; 3   jQuery = window.jQuery = window.$ = function(selector, context) { 4     return new jQuery.fn.init(selector, context); 5   }; 6   jQuery.fn = jQuery.prototype = { 7        init : function(selector, context) { 8          alert(selector); 9        }10   };11 })();12 window.onload = function() {13   $("div.red");//擷取"div.red"14   $("div .red");//擷取"div .red"15   $(document.getElementById("wrap"));//擷取"[object HTMLDivElement]"16   $("#wrap", document.forms[0]);//擷取"wrap"17   $("<div>hello, world</div>");//擷取"<div>hello, world</div>"18 }; 複製代碼  2. 盤根錯節的邏輯關係 jQuery()的4種構建jQuery對象的方式:   jQuery(expression, [context])   jQuery(html, [ownerDocument])   jQuery(elements)   jQuery(callback) jQuery對象的方法都是針對DOM元素對象進行的操作。 jQuery對象就是jQuery.fn.init構造器建立的對象,而通過jQuery.fn.init.prototype = jQuery.fn途徑,再使用jQuery的原型對象去覆蓋jQuery.fn的原型對象,使得jQuery對象的原型方法也就被繼承過來,從而形成了錯綜複雜但又井然有序的關係。   3. jQuery構造器 jQuery的構造器就是jQuery.fn.init()函數,它負責對傳入的參數進行分析,然後產生並返回jQuery對象。這個函數的第一個參數是必需的,如果為空白,則預設為document。從本質上講,使用jQuery選取器(即jQuery.fn.init()構造器)構建jQuery對象,就是在this對象上附加DOM元素集合,附加的方式包括以下兩種:  1. 如果是單個DOM元素,可以直接把DOM元素作為數組元素傳遞給this對象,還可以通過ID從DOM文檔中查詢元素  2. 如果是多個DOM元素,則以集合方式附加,如jQuery對象、數組和對象等,此時可以通過CSS選取器匹配到所有DOM元素,然後過濾,最後構建類數組的資料結構其中,CSS選取器是通過jQuery().find(selector)函數來完成的。通過jQuery().find(selector)可以分析選取器字串,並在DOM文檔樹中尋找到符合文法的元素集合。 下面先來分析一下init()初始化構造器函數,來分析jQuery選取器是如何工作的。 複製代碼 1 /** 2  * jQuery構造器源碼分析, 3  * 注意該書是以jQuery的1.3版本來分析的,與當前Github上的源碼的init函數有一定的出入, 4  * 但是整體的思路是差不多的,只是具體的實現方式有所不同而已, 5  */ 6 //jQuery原型函數,構造jQuery對象的入口 7 //所有jQuery對象方法都通過jQuery原型對象來繼承 8 jQuery.fn = jQuery.prototype = { 9     /*10      * jQuery對象初始化構造器,相當於jQuery對象的類型,有該函數負責建立jQuery對象11      * 參數說明:12      *         selector:選取器的符號,可以是任意資料類型。考慮DOM元素操作需要,該函數應該是包含DOM元素的任何資料13      *         context:上下文,指定在文檔DOM中哪個節點下開始進行查詢,預設值為document14      */15     init : function(selector, context) {16         selector = selector || document; //確保selector參數存在,預設值為document17         /*18          * 第一種情況,處理選擇符為DOM元素,此時將忽略上下文,即忽略第二個參數19          *         例如,$(document.getElementById("wrap")),jQuery(DOMElement)匹配DOM元素。20          *             先使用selector.nodeType判斷當selector為元素節點,將length設定為1,21          *             並且賦值給context,實際上context作為init的第二個參數,22          *             也意味著它的上下文節點就是selector該節點,返回它的$(DOMElement)對象23          */24         if(selector.nodeType) { //存在nodeType屬性,說明選擇符是一個DOM元素25             this[0] = selector; //直接把當前參數的DOM元素存入類數組中26             this.length = 1;    //設定類數組的長度,以方便遍曆訪問27             this.context = selector; //設定內容屬性28             return this;        //返回jQuery對象,即類數組對象29         }30         31         //如果選擇符參數為字串,則進行處理32         //例如,$("<div>hello, world</div>"),jQuery(html, [ownerDocument])匹配HTML字串33         if(typeof selector == "string") {34             //使用quickExprRegex匹配該選擇符字串,決定是處理HTML字串,還是處理ID字串35             quickExpr = /^[^<]*(<(.|\s)+>[^>]*$|^#([\w-]+)$)/;36             var match = quickExpr.exec(selector);37             //驗證匹配的資訊38             if(match && (match[1] || !context)) {39                 /*40                  * 第二種情況,處理HTML字串,類似$(html) -> $(array)41                  */42                 if(match[1]) {43                     selector = jQuery.clean([match[1]], context);44                 } 45                 /*46                  * 第三種情況,處理ID字串,類似$("#id")47                  */48                 else {49                     var elem = document.getElementById(match[3]);  //擷取該元素確保該元素存在50                     //處理在IE和Opera瀏覽器下根據name,而不是根據ID返回元素51                     if(elem && elem.id != match[3]) {52                         return jQuery().find(selector);    //預設調用document.find()方法53                     }54                     //否則將把elem作為元素參數直接調用jQuery()函數,返回jQuery對象55                     var ret = jQuery(elem || []); 56                     ret.context = document;        //設定jQuery對象的內容屬性57                     ret.selector = selector;    //設定jQuery對象上的選擇符屬性58                     return ret;                    //返回jQuery對象59                 }60             } 61             /*62              * 第四種情況,處理jQuery(expression, [context])63              *         例如,$("div .red")的運算式字串64              */65             else {66                 return jQuery(context).find(selector);67             }68         } else if(jQuery.isFunction(selector)) {69             /*70              * 第五種情況,處理jQuery(callback),即$(document).ready()的簡寫71              *         例如,$(function() { alert("hello, world");}),72              *         或者 $(document).ready(function() { alert("hello, world");})73              */74             return jQuery(document).ready(selector);75         }76         //確保舊的選擇符能夠通過77         if(selector.selector && selector.context) {78             this.selector = selector.selector;79             this.context = selector.context;80         }81         /*82          * 第六種情況,處理類似$(elements)83          */84         return this.setArray(jQuery.isArray(selector) ? selector : jQuery.makeArray(selector));85     }86     //其它代碼。。。87 };複製代碼代碼中已經對相關的判斷邏輯做了詳細的說明,這裡就不在做解釋說明了。 今天就先寫到這裡,下一篇內容將是關於jQuery如何產生DOM元素和引用DOM元素。歡迎轉載,轉載請註明出處。  

聯繫我們

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