jQuery源码解析之init
以下是对jquery-1.6.1.js中的init的解析,旨在分析ID选择器返回唯一一个匹配的元素(1),而多条件选择器返回的确是全部匹配的元素(2)。
(1)是ID选择器走的分支
(2)是多条件选择器走的分支
init: function( selector, context, rootjQuery ) {
var match, elem, ret, doc;
// 传入的selector为$(""), $(null), or $(undefined)
if ( !selector ) {
return this;
}
// 传入的selector是Dom元素,如document.getElementById("id")
//注解1
if ( selector.nodeType ) {
this.context = this[0] = selector;
this.length = 1;
return this;
}
if ( selector === "body" && !context && document.body ) {
this.context = document;
this[0] = document.body;
this.selector = selector;
this.length = 1;
return this;
}
// Handle HTML strings
if ( typeof selector === "string" ) {
// 传入"<tr>"
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 );
}
// Verify a match, and that no context was specified for #id
if ( match && (match[1] || !context) ) {
// HANDLE: $(html) -> $(array)
if ( match[1] ) {
context = context instanceof jQuery ? context[0] : context;
doc = (context ? context.ownerDocument || context : document);
// If a single string is passed in and it's a single tag
ret = rsingleTag.exec( selector ); // "<tr>" to "tr"
if ( ret ) {
if ( jQuery.isPlainObject( context ) ) {
selector = [ document.createElement( ret[1] ) ];
jQuery.fn.attr.call( selector, context, true ); //TODO
} else {
selector = [ doc.createElement( ret[1] ) ]; //createElement: "tr" --> "<tr>"
}
} else {
//传入的selector中不包括Element,例如"fff"
ret = jQuery.buildFragment( [ match[1] ], [ doc ] );
selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes; //return NodeList[<TextNode textContent="fff">]
}
return jQuery.merge( this, selector );
// HANDLE: $("#id")
} else {
//(1)是ID选择器走的分支
elem = document.getElementById( match[2] );
if ( elem && elem.parentNode ) {
// Handle the case where IE and Opera return items
// by name instead of ID
if ( elem.id !== match[2] ) {
return rootjQuery.find( selector );
}
// Otherwise, we inject the element directly into the jQuery object
//(1)是ID选择器走的分支
this.length = 1;
this[0] = elem;
}
this.context = document;
this.selector = selector;
return this;
}
// HANDLE: $(expr, $(...))
} else if ( !context || context.jquery ) {
//(2)是多条件选择器走的分支
return (context || rootjQuery).find( selector );
// HANDLE: $(expr, context)
// (which is just equivalent to: $(context).find(expr)
} else {
return this.constructor( context ).find( selector );
}
// HANDLE: $(function)
// Shortcut for document ready
} else if ( jQuery.isFunction( selector ) ) {
return rootjQuery.ready( selector );
}
if (selector.selector !== undefined) {
this.selector = selector.selector;
this.context = selector.context;
}
return jQuery.makeArray( selector, this );
}ID选择器和多条件选择器Demo:
$("#id");
$("#id1, #id2");上面的例子在调用init创建就Query对象的时候,根本没有传递context,这里借用http://api.jquery.com/context/中的一句话来解释一下:Thevalueofthispropertyistypicallyequaltodocument,asthisisthedefaultcontextforjQueryobjectsifnoneissupplied.Thecontextmaydifferif,forexample,theobjectwascreatedbysearchingwithinan<iframe>orXMLdocument.
总结:(context||rootjQuery).find(selector);实际上是执行的document.find(selector);
注解1:关于这个分支的运用,举例如下:
var elem = document.getElementById("id_list[4521216583]");//返回的是Dom元素
//将Dom元素转为jquery对象的方法,也就是传入一个Dom元素,走注解1所在的分支
var $elem = $(elem);
//顺带解释一下,.value和.val()的区别
//value是Dom元素的属性
//val是jquery对象所有的
elem.value;
$elem.val(); 相关推荐
瓜牛呱呱 2020-11-12
柳木木的IT 2020-11-04
yifouhu 2020-11-02
lei0 2020-11-02
源码zanqunet 2020-10-26
码代码的陈同学 2020-10-14
lukezhong 2020-10-14
clh0 2020-09-18
changcongying 2020-09-17
星辰大海的路上 2020-09-13
abfdada 2020-08-26
mzy000 2020-08-24
shenlanse 2020-08-18
zhujiangtaotaise 2020-08-18
xiemanR 2020-08-17