摘要:源碼中接受個參數,空參數,這個會直接返回一個空的對象,。,這是一個標準且常用法,表示一個選擇器,這個選擇器通常是一個字符串,或者等,表示選擇范圍,即限定作用,可為,對象。,會把普通的對象或對象包裝在對象中。介紹完入口,就開始來看源碼。
歡迎來我的專欄查看系列文章。
init 構造器前面一講總體架構已經介紹了 jQuery 的基本情況,這一章主要來介紹 jQuery 的入口函數 jQuery.fn.init。
由于這個函數直接和 jQuery() 的參數有關,先來說下能接受什么樣的參數。源碼中接受 3 個參數:
init: function (selector, context, root) { ... }
jQuery(),空參數,這個會直接返回一個空的 jQuery 對象,return this。
jQuery( selector [, context ] ),這是一個標準且常用法,selector 表示一個 css 選擇器,這個選擇器通常是一個字符串,#id 或者 .class 等,context 表示選擇范圍,即限定作用,可為 DOM,jQuery 對象。
jQuery( element|elements ),用于將一個 DOM 對象或 DOM 數組封裝成 jQuery 對象。
jQuery( jQuery object|object ),會把普通的對象或 jQuery 對象包裝在 jQuery 對象中。
jQuery( html [, ownerDocument ] ),這個方法用于將 html 字符串先轉成 DOM 對象后在生成 jQuery 對象。
jQuery( html, attributes ),和上一個方法一樣,不過會將 attributes 中的方法和屬性綁定到生成的 html DOM 中,比如 class 等。
jQuery( callback ),此方法接受一個回掉函數,相當于 window.onload 方法,只是相對于。
jQuery.fn.init介紹完入口,就開始來看源碼。
init: function (selector, context, root) { var match, elem; // 處理: $(""), $(null), $(undefined), $(false) if (!selector) { return this; } // rootjQuery = jQuery( document ); root = root || rootjQuery; // 處理 HTML 字符串情況,包括 $("")、$("#id")、$(".class") if (typeof selector === "string") { //此部分拆分,留在后面講 // HANDLE: $(DOMElement) } else if (selector.nodeType) { this[0] = selector; this.length = 1; return this; // HANDLE: $(function) } else if (jQuery.isFunction(selector)) { return root.ready !== undefined ? root.ready(selector) : // Execute immediately if ready is not present selector(jQuery); } return jQuery.makeArray(selector, this); }上面有幾點需要注意,root = root || rootjQuery;,這個參數在前面介紹用法的時候,就沒有提及,這個表示 document,默認的話是 rootjQuery,而 rootjQuery = jQuery( document )。
可以看出,對于處理 $(DOMElement),直接是把 jQuery 當作一個數組,this[0] = DOMElement。其實,這要從 jQuery 的基本構造講起,我們完成一個 $("div.span") 之后,然后一個 jQuery 對象(this),其中會得到一組(一個)DOM 對象,jQuery 會把這組 DOM 對象當作數組元素添加過來,并給一個 length。后面就像一些鏈式函數操作的時候,若只能對一個 DOM 操作,比如 width、height,就只對第一個元素操作,若可以對多個 DOM 操作,則會對所有 DOM 進行操作,比如 css()。
jQuery 大題思路如下,這是一個非常簡單點實現:
jQuery.prototype = { // 簡單點,假設此時 selector 用 querySelectorAll init: function(selector){ var ele = document.querySelectorAll(selector); // 把 this 當作數組,每一項都是 DOM 對象 for(var i = 0; i < ele.length; i++){ this[i] = ele[i]; } this.length = ele.length; return this; }, //css 若只有一個對象,則取其第一個 DOM 對象 //若 css 有兩個參數,則對每一個 DOM 對象都設置 css css : function(attr,val){ for(var i = 0; i < this.length; i++){ if(val == undefined){ if(typeof attr === "object"){ for(var key in attr){ this.css(key, attr[key]); } }else if(typeof attr === "string"){ return getComputedStyle(this[i])[attr]; } }else{ this[i].style[attr] = val; } } }, }所以對于 DOMElement 的處理,直接將 DOM 賦值給數組后,return this。
jQuery.makeArray 是一個綁定 數組的函數,和上面的原理一樣,后面會談到。
在介紹下面的內容之前,先來介紹一個 jQuery 中一個識別 Html 字符串的正則表達式,
var rquickExpr = /^(?:s*(<[wW]+>)[^>]*|#([w-]+))$/; rquickExpr.exec("") //["", "", undefined] rquickExpr.exec("") //["", "", undefined] rquickExpr.exec("#id") //["#id", undefined, "id"] rquickExpr.exec(".class") //null上面這一系列的正則表達式 exec,只是為了說明 rquickExpr 這個正則表達式執行后的結果,首先,如果匹配到,結果數組的長度是 3,如果匹配到
這種 html,數組的第三個元素是 underfined,如果匹配到 #id,數組的第二個元素是 underfined,如果匹配不到,則為 null。另外還有一個正則表達式:
var rsingleTag = ( /^<([a-z][^/