Sizzle 源码分析

解析Sizzle的源码首先从Sizzle的入口开始

/**
	 * 
	 * 这个方法是Sizzle 的入口
	 */
	var Sizzle = function(selector, context, results, seed) {
		/**
		 * results是保存结果的数组 context默认为document 各种局部变量的定义
		 */
		results = results || [];
		context = context || document;
		var match, elem, contextXML, m, nodeType = context.nodeType;
		// nodeType ==9说明context是document nodeType ==1表示context是element
		if (nodeType !== 1 && nodeType !== 9) {
			return [];
		}
		// 如果选择器不是字符串或者为空 返回一个空的数组
		if (!selector || typeof selector !== "string") {
			return results;
		}
		// 是否是xml格式
		contextXML = isXML(context);
		// seed是预留的参数 一般情况下不会有值
		if (!contextXML && !seed) {
			/**
			 * rquickExpr正则表达式匹配#号.号开头后接多个单词字符包括上划线- 或者多个单词字符 一旦匹配成功------------
			 * match[1]对应 #ID -----------match[2]对应 TAG -------match[3]对应 .class
			 * 
			 */
			if ((match = rquickExpr.exec(selector))) {
				/**
				 * 处理Sizzle("#ID")
				 */
				// Speed-up: Sizzle("#ID")
				if ((m = match[1])) {
					// 如果上下文是document 可以直接使用document.getElementById方法获取元素
					if (nodeType === 9) {
						elem = context.getElementById(m);
						// Check parentNode to catch when Blackberry 4.6 returns
						// nodes that are no longer in the document #6963
						if (elem && elem.parentNode) {
							// Handle the case where IE, Opera, and Webkit
							// return items
							// by name instead of ID
							if (elem.id === m) {
								/**
								 * makeArray的作用就是合并两个对象或者数组 并返回合并后的数组或对象
								 * 把结果保存到results
								 */
								return makeArray([elem], results);
							}
						} else {
							return makeArray([], results);
						}
					} else {
						/**
						 * 如果Context不是document 先通过ownerDocument属性取得document
						 * 然后在再通过document.getElementById来获取element
						 */
						// Context is not a document
						if (context.ownerDocument
								&& (elem = context.ownerDocument
										.getElementById(m))
								&& contains(context, elem) && elem.id === m) {
							return makeArray([elem], results);
						}
					}
					/**
					 * 处理 Sizzle("TAG")
					 * 通过element元素的getElementsByTagName方法获取选择器表达式
					 */
					// Speed-up: Sizzle("TAG")
				} else if (match[2]) {
					return makeArray(context.getElementsByTagName(selector),
							results);
					/**
					 * 处理 Sizzle(".CLASS")
					 * assertUsableClassName测试各个浏览器element是否支持getElementsByClassName方法
					 * 
					 */
					// Speed-up: Sizzle(".CLASS")
				} else if (assertUsableClassName && (m = match[3])
						&& context.getElementsByClassName) {
					return makeArray(context.getElementsByClassName(m), results);
				}
			}
		}

		// All others
		return select(selector, context, results, seed, contextXML);
	};

相关推荐