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/中的一句话来解释一下:The value of this property is typically equal to document, as this is the default context for jQuery objects if none is supplied. The context may differ if, for example, the object was created by searching within an <iframe> or XML document.
总结:(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();

你可能感兴趣的:(jquery)