jquery構(gòu)造器的實(shí)現(xiàn)代碼小結(jié)
更新時(shí)間:2011年05月16日 01:54:04 作者:
jQuery的$符號(hào)非常神奇,它可以接受一個(gè)字符,也可以接受一個(gè)文檔對(duì)象或window對(duì)象,亦可以傳個(gè)函數(shù)進(jìn)行變?yōu)閐omReady加載器
顯然,能做到這一步,其實(shí)現(xiàn)是相當(dāng)?shù)膹?fù)雜,這個(gè)實(shí)現(xiàn)就是它的init方法,jQuery的真實(shí)構(gòu)造器。它功能也隨著版本的升級(jí)而升級(jí),越來(lái)越長(zhǎng)。
2009-01-13發(fā)布的1.3版
init: function( selector, context ) {
// Make sure that a selection was provided
selector = selector || document;
// 處理節(jié)點(diǎn)參數(shù),直接添加屬性到新實(shí)例上
if ( selector.nodeType ) {
this[0] = selector;
this.length = 1;
this.context = selector;
return this;
}
// 處理字符串參數(shù)
if ( typeof selector === "string" ) {
// 判定是否為HTML片斷還是ID
var match = quickExpr.exec( selector );
if ( match && (match[1] || !context) ) {
// 如果是HTML片斷,轉(zhuǎn)換一個(gè)由節(jié)點(diǎn)構(gòu)造的數(shù)組
if ( match[1] )
selector = jQuery.clean( [ match[1] ], context );
// 如果是ID,則查找此元素,如果找到放進(jìn)空數(shù)組中
else {
var elem = document.getElementById( match[3] );
// Make sure an element was located
if ( elem ){
// 處理 IE and Opera 混淆ID與NAME的bug
if ( elem.id != match[3] )
return jQuery().find( selector );
var ret = jQuery( elem );
ret.context = document;
ret.selector = selector;
return ret;
}
selector = [];
}
} else
//使用Sizzle處理其他CSS表達(dá)式,生成實(shí)例并返回
return jQuery( context ).find( selector );
// 處理函數(shù)參數(shù),直接domReady
} else if ( jQuery.isFunction( selector ) )
return jQuery( document ).ready( selector );
//處理jQuery對(duì)象參數(shù),簡(jiǎn)單地將其兩個(gè)屬性賦給新實(shí)例
if ( selector.selector && selector.context ) {
this.selector = selector.selector;
this.context = selector.context;
}
//將上面得到節(jié)點(diǎn)數(shù)組,用setArray方法把它們變成實(shí)例的元素
return this.setArray(jQuery.makeArray(selector));
},
2009-02-19發(fā)布的1.32版
init: function( selector, context ) {
// Make sure that a selection was provided
selector = selector || document;
// 處理節(jié)點(diǎn)參數(shù),直接添加屬性到新實(shí)例上
if ( selector.nodeType ) {
this[0] = selector;
this.length = 1;
this.context = selector;
return this;
}
//處理字符串參數(shù)
if ( typeof selector === "string" ) {
//判定是否為HTML片斷還是ID
var match = quickExpr.exec( selector );
if ( match && (match[1] || !context) ) {
// 如果是HTML片斷,轉(zhuǎn)換一個(gè)由節(jié)點(diǎn)構(gòu)造的數(shù)組
if ( match[1] )
selector = jQuery.clean( [ match[1] ], context );
else {
var elem = document.getElementById( match[3] );
// 如果是ID,則查找此元素,如果找到放進(jìn)空數(shù)組中
if ( elem && elem.id != match[3] )
return jQuery().find( selector );
//這里對(duì)1.3版做了些優(yōu)化,更簡(jiǎn)潔
var ret = jQuery( elem || [] );
ret.context = document;
ret.selector = selector;
return ret;
}
} else
//使用Sizzle處理其他CSS表達(dá)式,生成實(shí)例并返回
return jQuery( context ).find( selector );
// 處理函數(shù)參數(shù),進(jìn)行domReady操作
} else if ( jQuery.isFunction( selector ) )
return jQuery( document ).ready( selector );
//處理jQuery對(duì)象參數(shù),簡(jiǎn)單地將其兩個(gè)屬性賦給新實(shí)例
if ( selector.selector && selector.context ) {
this.selector = selector.selector;
this.context = selector.context;
}
//這里對(duì)1.3版做了些擴(kuò)展,允許傳珍上元素集合(HTMLCollection)與節(jié)點(diǎn)集合(NodeList),
//元素?cái)?shù)組可能是我們用字符串轉(zhuǎn)換過(guò)來(lái)的,也可以是用戶(hù)直接傳進(jìn)來(lái)的
return this.setArray(jQuery.isArray( selector ) ? selector : jQuery.makeArray(selector));
},
2010-01-13發(fā)布的1.4版
init: function( selector, context ) {
var match, elem, ret, doc;
//處理空白字符串,null,undefined參數(shù)(新增),返回一個(gè)非常純凈的實(shí)例
if ( !selector ) {
return this;
}
// 處理節(jié)點(diǎn)參數(shù),直接添加屬性到新實(shí)例上
if ( selector.nodeType ) {
this.context = this[0] = selector;//寫(xiě)法上優(yōu)化
this.length = 1;
return this;
}
//處理字符串參數(shù)
if ( typeof selector === "string" ) {
// 判定是否為HTML片斷還是ID
match = quickExpr.exec( selector );
if ( match && (match[1] || !context) ) {
//如果是HTML片斷
if ( match[1] ) {
//取得文檔對(duì)象
doc = (context ? context.ownerDocument || context : document);
// 如果是單個(gè)標(biāo)簽,直接使用 document.createElement創(chuàng)建此節(jié)點(diǎn)并放入數(shù)組中
ret = rsingleTag.exec( selector );
if ( ret ) {
//如果后面跟著一個(gè)純凈的JS對(duì)象,則為此節(jié)點(diǎn)添加相應(yīng)的屬性或樣式
if ( jQuery.isPlainObject( context ) ) {
selector = [ document.createElement( ret[1] ) ];
jQuery.fn.attr.call( selector, context, true );
} else {
selector = [ doc.createElement( ret[1] ) ];
}
} else {
//改由buildFragment來(lái)生成節(jié)點(diǎn)集合(NodeList)
ret = buildFragment( [ match[1] ], [ doc ] );
selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
}
} else {
// 如果是ID,則查找此元素,如果找到放進(jìn)空數(shù)組中
elem = document.getElementById( match[2] );
if ( elem ) {
// 處理 IE and Opera 混淆ID與NAME的bug
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector );
}
//這里也做了一些優(yōu)化,原來(lái)是很傻地再生成一個(gè)jQuery實(shí)例
this.length = 1;
this[0] = elem;
}
this.context = document;
this.selector = selector;
return this;
}
// 如果字符是很簡(jiǎn)單的標(biāo)簽選擇器,那基本沒(méi)有必要走Sizzle路線,直接getElementsByTagName,很好的優(yōu)化
} else if ( !context && /^\w+$/.test( selector ) ) {
this.selector = selector;
this.context = document;
selector = document.getElementsByTagName( selector );
// 如果第二個(gè)參數(shù)不存在或者是jQuery對(duì)象,那么用它或rootjQuery調(diào)用find查找目標(biāo)節(jié)點(diǎn)(走Sizzle路線)
} else if ( !context || context.jquery ) {
return (context || rootjQuery).find( selector );
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
//如果第二個(gè)參數(shù)已指定為某元素節(jié)點(diǎn),轉(zhuǎn)為jQuery對(duì)象,走Sizzle路線
return jQuery( context ).find( selector );
}
// 處理函數(shù)參數(shù),直接domReady
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
//處理jQuery對(duì)象參數(shù),簡(jiǎn)單地將其兩個(gè)屬性賦給新實(shí)例
if (selector.selector !== undefined) {
this.selector = selector.selector;
this.context = selector.context;
}
//這里又做了些許修改,緣于makeArray可以接受第二個(gè)參數(shù)(可以是數(shù)組或類(lèi)數(shù)組,這時(shí)相當(dāng)合并操作)
return jQuery.isArray( selector ) ?
this.setArray( selector ) ://內(nèi)部用push方法,迅速將一個(gè)普通對(duì)象變成類(lèi)數(shù)組對(duì)象
jQuery.makeArray( selector, this );
},
接著是廣受歡迎的2010-02-13發(fā)布的1.42版
init: function( selector, context ) {
var match, elem, ret, doc;
// 處理空白字符串,null,undefined參數(shù)
if ( !selector ) {
return this;
}
// 處理節(jié)點(diǎn)參數(shù)
if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;
}
// 處理body參數(shù)(新增)
if ( selector === "body" && !context ) {
this.context = document;
this[0] = document.body;
this.selector = "body";
this.length = 1;
return this;
}
// 處理字符串參數(shù),分七種情形:
//①單個(gè)標(biāo)簽,帶對(duì)象屬性包 ---> jQuery.merge
//②單個(gè)標(biāo)簽,不帶對(duì)象屬性包 ---> attr + jQuery.merge
//③復(fù)雜的HTML片斷 ---> buildFragment + jQuery.merge
//④ID選擇器,與找到的元素的ID不同 ---> getElementById + Sizzle + pushStack
//⑤ID選擇器,與找到的元素的ID相同 ---> getElementById + 簡(jiǎn)單屬性添加
//⑥標(biāo)簽選擇器 ---> getElementsByTagName + jQuery.merge
//⑦其他CSS表達(dá)式 ---> Sizzle + pushStack
if ( typeof selector === "string" ) {
match = quickExpr.exec( selector );
if ( match && (match[1] || !context) ) {
if ( match[1] ) {
doc = (context ? context.ownerDocument || context : document);
ret = rsingleTag.exec( selector );
if ( ret ) {
if ( jQuery.isPlainObject( context ) ) {
selector = [ document.createElement( ret[1] ) ];
jQuery.fn.attr.call( selector, context, true );
} else {
selector = [ doc.createElement( ret[1] ) ];
}
} else {
ret = buildFragment( [ match[1] ], [ doc ] );
selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
}
return jQuery.merge( this, selector );
} else {
elem = document.getElementById( match[2] );
if ( elem ) {
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector );
}
this.length = 1;
this[0] = elem;
}
this.context = document;
this.selector = selector;
return this;
}
} else if ( !context && /^\w+$/.test( selector ) ) {
this.selector = selector;
this.context = document;
selector = document.getElementsByTagName( selector );
return jQuery.merge( this, selector );
} else if ( !context || context.jquery ) {
return (context || rootjQuery).find( selector );
} else {
return jQuery( context ).find( selector );
}
// 處理函數(shù)參數(shù),直接domReady
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
//處理jQuery對(duì)象參數(shù)
if (selector.selector !== undefined) {
this.selector = selector.selector;
this.context = selector.context;
}
//無(wú)論是數(shù)組還是類(lèi)數(shù)組(如NodeList),統(tǒng)統(tǒng)使用jQuery.makeArray來(lái)為實(shí)例添加新的元素
return jQuery.makeArray( selector, this );
},
另附上makeArray方法與merge方法,merge方法好神奇啊,
makeArray: function( array, results ) {
var ret = results || [];
if ( array != null ) {
// The window, strings (and functions) also have 'length'
// The extra typeof function check is to prevent crashes
// in Safari 2 (See: #3039)
if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
push.call( ret, array );
} else {
jQuery.merge( ret, array );
}
}
return ret;
},
merge: function( first, second ) {
var i = first.length, j = 0;
if ( typeof second.length === "number" ) {
for ( var l = second.length; j < l; j++ ) {
first[ i++ ] = second[ j ];
}
} else {
while ( second[j] !== undefined ) {
first[ i++ ] = second[ j++ ];
}
}
first.length = i;
return first;
},
2011-01-23發(fā)布的1.5版,其init方法與1.42的變化不大:只有兩處做了改動(dòng):
//1.42
- ret = buildFragment( [ match[1] ], [ doc ] );
- selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
//1.5
+ ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
+ selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
//1.42
- return jQuery( context ).find( selector );
//1.5
+ return this.constructor( context ).find( selector );//目的就是為了不再生成新實(shí)例
2011-05-02發(fā)布的jquery1.6,變化不大,只是對(duì)HTML片斷進(jìn)行了更嚴(yán)密的判定:
// Are we dealing with HTML string or an ID?
if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [ null, selector, null ];
} else {
match = quickExpr.exec( selector );
}
總體來(lái)說(shuō),jQuery的構(gòu)造器已經(jīng)做得非常之完美,基本上達(dá)到“改無(wú)可改”的地步了。但是要保證其高效運(yùn)作,我們還需要一點(diǎn)選擇器的知識(shí)與了解buildFragment方法的運(yùn)作,因?yàn)檫@兩個(gè)實(shí)在太常用了,但也是最耗性能的。
2009-01-13發(fā)布的1.3版
復(fù)制代碼 代碼如下:
init: function( selector, context ) {
// Make sure that a selection was provided
selector = selector || document;
// 處理節(jié)點(diǎn)參數(shù),直接添加屬性到新實(shí)例上
if ( selector.nodeType ) {
this[0] = selector;
this.length = 1;
this.context = selector;
return this;
}
// 處理字符串參數(shù)
if ( typeof selector === "string" ) {
// 判定是否為HTML片斷還是ID
var match = quickExpr.exec( selector );
if ( match && (match[1] || !context) ) {
// 如果是HTML片斷,轉(zhuǎn)換一個(gè)由節(jié)點(diǎn)構(gòu)造的數(shù)組
if ( match[1] )
selector = jQuery.clean( [ match[1] ], context );
// 如果是ID,則查找此元素,如果找到放進(jìn)空數(shù)組中
else {
var elem = document.getElementById( match[3] );
// Make sure an element was located
if ( elem ){
// 處理 IE and Opera 混淆ID與NAME的bug
if ( elem.id != match[3] )
return jQuery().find( selector );
var ret = jQuery( elem );
ret.context = document;
ret.selector = selector;
return ret;
}
selector = [];
}
} else
//使用Sizzle處理其他CSS表達(dá)式,生成實(shí)例并返回
return jQuery( context ).find( selector );
// 處理函數(shù)參數(shù),直接domReady
} else if ( jQuery.isFunction( selector ) )
return jQuery( document ).ready( selector );
//處理jQuery對(duì)象參數(shù),簡(jiǎn)單地將其兩個(gè)屬性賦給新實(shí)例
if ( selector.selector && selector.context ) {
this.selector = selector.selector;
this.context = selector.context;
}
//將上面得到節(jié)點(diǎn)數(shù)組,用setArray方法把它們變成實(shí)例的元素
return this.setArray(jQuery.makeArray(selector));
},
2009-02-19發(fā)布的1.32版
復(fù)制代碼 代碼如下:
init: function( selector, context ) {
// Make sure that a selection was provided
selector = selector || document;
// 處理節(jié)點(diǎn)參數(shù),直接添加屬性到新實(shí)例上
if ( selector.nodeType ) {
this[0] = selector;
this.length = 1;
this.context = selector;
return this;
}
//處理字符串參數(shù)
if ( typeof selector === "string" ) {
//判定是否為HTML片斷還是ID
var match = quickExpr.exec( selector );
if ( match && (match[1] || !context) ) {
// 如果是HTML片斷,轉(zhuǎn)換一個(gè)由節(jié)點(diǎn)構(gòu)造的數(shù)組
if ( match[1] )
selector = jQuery.clean( [ match[1] ], context );
else {
var elem = document.getElementById( match[3] );
// 如果是ID,則查找此元素,如果找到放進(jìn)空數(shù)組中
if ( elem && elem.id != match[3] )
return jQuery().find( selector );
//這里對(duì)1.3版做了些優(yōu)化,更簡(jiǎn)潔
var ret = jQuery( elem || [] );
ret.context = document;
ret.selector = selector;
return ret;
}
} else
//使用Sizzle處理其他CSS表達(dá)式,生成實(shí)例并返回
return jQuery( context ).find( selector );
// 處理函數(shù)參數(shù),進(jìn)行domReady操作
} else if ( jQuery.isFunction( selector ) )
return jQuery( document ).ready( selector );
//處理jQuery對(duì)象參數(shù),簡(jiǎn)單地將其兩個(gè)屬性賦給新實(shí)例
if ( selector.selector && selector.context ) {
this.selector = selector.selector;
this.context = selector.context;
}
//這里對(duì)1.3版做了些擴(kuò)展,允許傳珍上元素集合(HTMLCollection)與節(jié)點(diǎn)集合(NodeList),
//元素?cái)?shù)組可能是我們用字符串轉(zhuǎn)換過(guò)來(lái)的,也可以是用戶(hù)直接傳進(jìn)來(lái)的
return this.setArray(jQuery.isArray( selector ) ? selector : jQuery.makeArray(selector));
},
2010-01-13發(fā)布的1.4版
復(fù)制代碼 代碼如下:
init: function( selector, context ) {
var match, elem, ret, doc;
//處理空白字符串,null,undefined參數(shù)(新增),返回一個(gè)非常純凈的實(shí)例
if ( !selector ) {
return this;
}
// 處理節(jié)點(diǎn)參數(shù),直接添加屬性到新實(shí)例上
if ( selector.nodeType ) {
this.context = this[0] = selector;//寫(xiě)法上優(yōu)化
this.length = 1;
return this;
}
//處理字符串參數(shù)
if ( typeof selector === "string" ) {
// 判定是否為HTML片斷還是ID
match = quickExpr.exec( selector );
if ( match && (match[1] || !context) ) {
//如果是HTML片斷
if ( match[1] ) {
//取得文檔對(duì)象
doc = (context ? context.ownerDocument || context : document);
// 如果是單個(gè)標(biāo)簽,直接使用 document.createElement創(chuàng)建此節(jié)點(diǎn)并放入數(shù)組中
ret = rsingleTag.exec( selector );
if ( ret ) {
//如果后面跟著一個(gè)純凈的JS對(duì)象,則為此節(jié)點(diǎn)添加相應(yīng)的屬性或樣式
if ( jQuery.isPlainObject( context ) ) {
selector = [ document.createElement( ret[1] ) ];
jQuery.fn.attr.call( selector, context, true );
} else {
selector = [ doc.createElement( ret[1] ) ];
}
} else {
//改由buildFragment來(lái)生成節(jié)點(diǎn)集合(NodeList)
ret = buildFragment( [ match[1] ], [ doc ] );
selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
}
} else {
// 如果是ID,則查找此元素,如果找到放進(jìn)空數(shù)組中
elem = document.getElementById( match[2] );
if ( elem ) {
// 處理 IE and Opera 混淆ID與NAME的bug
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector );
}
//這里也做了一些優(yōu)化,原來(lái)是很傻地再生成一個(gè)jQuery實(shí)例
this.length = 1;
this[0] = elem;
}
this.context = document;
this.selector = selector;
return this;
}
// 如果字符是很簡(jiǎn)單的標(biāo)簽選擇器,那基本沒(méi)有必要走Sizzle路線,直接getElementsByTagName,很好的優(yōu)化
} else if ( !context && /^\w+$/.test( selector ) ) {
this.selector = selector;
this.context = document;
selector = document.getElementsByTagName( selector );
// 如果第二個(gè)參數(shù)不存在或者是jQuery對(duì)象,那么用它或rootjQuery調(diào)用find查找目標(biāo)節(jié)點(diǎn)(走Sizzle路線)
} else if ( !context || context.jquery ) {
return (context || rootjQuery).find( selector );
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
//如果第二個(gè)參數(shù)已指定為某元素節(jié)點(diǎn),轉(zhuǎn)為jQuery對(duì)象,走Sizzle路線
return jQuery( context ).find( selector );
}
// 處理函數(shù)參數(shù),直接domReady
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
//處理jQuery對(duì)象參數(shù),簡(jiǎn)單地將其兩個(gè)屬性賦給新實(shí)例
if (selector.selector !== undefined) {
this.selector = selector.selector;
this.context = selector.context;
}
//這里又做了些許修改,緣于makeArray可以接受第二個(gè)參數(shù)(可以是數(shù)組或類(lèi)數(shù)組,這時(shí)相當(dāng)合并操作)
return jQuery.isArray( selector ) ?
this.setArray( selector ) ://內(nèi)部用push方法,迅速將一個(gè)普通對(duì)象變成類(lèi)數(shù)組對(duì)象
jQuery.makeArray( selector, this );
},
接著是廣受歡迎的2010-02-13發(fā)布的1.42版
復(fù)制代碼 代碼如下:
init: function( selector, context ) {
var match, elem, ret, doc;
// 處理空白字符串,null,undefined參數(shù)
if ( !selector ) {
return this;
}
// 處理節(jié)點(diǎn)參數(shù)
if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;
}
// 處理body參數(shù)(新增)
if ( selector === "body" && !context ) {
this.context = document;
this[0] = document.body;
this.selector = "body";
this.length = 1;
return this;
}
// 處理字符串參數(shù),分七種情形:
//①單個(gè)標(biāo)簽,帶對(duì)象屬性包 ---> jQuery.merge
//②單個(gè)標(biāo)簽,不帶對(duì)象屬性包 ---> attr + jQuery.merge
//③復(fù)雜的HTML片斷 ---> buildFragment + jQuery.merge
//④ID選擇器,與找到的元素的ID不同 ---> getElementById + Sizzle + pushStack
//⑤ID選擇器,與找到的元素的ID相同 ---> getElementById + 簡(jiǎn)單屬性添加
//⑥標(biāo)簽選擇器 ---> getElementsByTagName + jQuery.merge
//⑦其他CSS表達(dá)式 ---> Sizzle + pushStack
if ( typeof selector === "string" ) {
match = quickExpr.exec( selector );
if ( match && (match[1] || !context) ) {
if ( match[1] ) {
doc = (context ? context.ownerDocument || context : document);
ret = rsingleTag.exec( selector );
if ( ret ) {
if ( jQuery.isPlainObject( context ) ) {
selector = [ document.createElement( ret[1] ) ];
jQuery.fn.attr.call( selector, context, true );
} else {
selector = [ doc.createElement( ret[1] ) ];
}
} else {
ret = buildFragment( [ match[1] ], [ doc ] );
selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
}
return jQuery.merge( this, selector );
} else {
elem = document.getElementById( match[2] );
if ( elem ) {
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector );
}
this.length = 1;
this[0] = elem;
}
this.context = document;
this.selector = selector;
return this;
}
} else if ( !context && /^\w+$/.test( selector ) ) {
this.selector = selector;
this.context = document;
selector = document.getElementsByTagName( selector );
return jQuery.merge( this, selector );
} else if ( !context || context.jquery ) {
return (context || rootjQuery).find( selector );
} else {
return jQuery( context ).find( selector );
}
// 處理函數(shù)參數(shù),直接domReady
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
//處理jQuery對(duì)象參數(shù)
if (selector.selector !== undefined) {
this.selector = selector.selector;
this.context = selector.context;
}
//無(wú)論是數(shù)組還是類(lèi)數(shù)組(如NodeList),統(tǒng)統(tǒng)使用jQuery.makeArray來(lái)為實(shí)例添加新的元素
return jQuery.makeArray( selector, this );
},
另附上makeArray方法與merge方法,merge方法好神奇啊,
復(fù)制代碼 代碼如下:
makeArray: function( array, results ) {
var ret = results || [];
if ( array != null ) {
// The window, strings (and functions) also have 'length'
// The extra typeof function check is to prevent crashes
// in Safari 2 (See: #3039)
if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {
push.call( ret, array );
} else {
jQuery.merge( ret, array );
}
}
return ret;
},
merge: function( first, second ) {
var i = first.length, j = 0;
if ( typeof second.length === "number" ) {
for ( var l = second.length; j < l; j++ ) {
first[ i++ ] = second[ j ];
}
} else {
while ( second[j] !== undefined ) {
first[ i++ ] = second[ j++ ];
}
}
first.length = i;
return first;
},
2011-01-23發(fā)布的1.5版,其init方法與1.42的變化不大:只有兩處做了改動(dòng):
復(fù)制代碼 代碼如下:
//1.42
- ret = buildFragment( [ match[1] ], [ doc ] );
- selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;
//1.5
+ ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
+ selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;
//1.42
- return jQuery( context ).find( selector );
//1.5
+ return this.constructor( context ).find( selector );//目的就是為了不再生成新實(shí)例
2011-05-02發(fā)布的jquery1.6,變化不大,只是對(duì)HTML片斷進(jìn)行了更嚴(yán)密的判定:
復(fù)制代碼 代碼如下:
// Are we dealing with HTML string or an ID?
if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {
// Assume that strings that start and end with <> are HTML and skip the regex check
match = [ null, selector, null ];
} else {
match = quickExpr.exec( selector );
}
總體來(lái)說(shuō),jQuery的構(gòu)造器已經(jīng)做得非常之完美,基本上達(dá)到“改無(wú)可改”的地步了。但是要保證其高效運(yùn)作,我們還需要一點(diǎn)選擇器的知識(shí)與了解buildFragment方法的運(yùn)作,因?yàn)檫@兩個(gè)實(shí)在太常用了,但也是最耗性能的。
相關(guān)文章
jQuery移除tr無(wú)效的解決方法(tr是動(dòng)態(tài)添加)
移除掉某些tr(tr是動(dòng)態(tài)添加的)嘗試了很多方法,都不見(jiàn)效,后來(lái)發(fā)現(xiàn)個(gè)不錯(cuò)的方法,于是與大家分享下2014-09-09Jquery鼠標(biāo)放上去顯示全名的實(shí)現(xiàn)方法
下面小編就為大家?guī)?lái)一篇Jquery鼠標(biāo)放上去顯示全名的實(shí)現(xiàn)方法。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02在JavaScript的jQuery庫(kù)中操作AJAX的方法講解
這篇文章主要介紹了在JavaScript的jQuery庫(kù)中操作AJAX的方法講解,包括利用jQuery簡(jiǎn)化Ajax開(kāi)發(fā)部分的內(nèi)容,需要的朋友可以參考下2015-08-08jquery實(shí)現(xiàn)彈出層登錄和全屏層注冊(cè)特效
這篇文章主要為大家詳細(xì)介紹了jquery實(shí)現(xiàn)彈出層登錄和全屏層注冊(cè)特效,推薦給大家,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2015-08-08jQuery Collapse1.1.0折疊插件簡(jiǎn)單使用
這篇文章主要介紹了jQuery Collapse1.1.0折疊插件的使用方法 ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-08-08jquery批量設(shè)置屬性readonly和disabled的方法
批量設(shè)置屬性的方法有很多,在本文為大家介紹下使用jquery批量設(shè)置readonly和disabled屬性2014-01-01jQuery實(shí)現(xiàn)的簡(jiǎn)單拖動(dòng)層示例
這篇文章主要介紹了jQuery實(shí)現(xiàn)的簡(jiǎn)單拖動(dòng)層,可實(shí)現(xiàn)響應(yīng)鼠標(biāo)拖動(dòng)div層及動(dòng)態(tài)顯示坐標(biāo)值的功能,涉及jQuery鼠標(biāo)響應(yīng)及頁(yè)面元素屬性相關(guān)操作技巧,需要的朋友可以參考下2017-02-02