亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

jQuery選擇器源碼解讀(一):Sizzle方法

2019-11-20 12:49:40
字體:
來源:轉載
供稿:網友

對jQuery的Sizzle各方法做了深入分析(同時也參考了一些網上資料)后,將結果分享給大家。我將采用連載的方式,對Sizzle使用的一些方法詳細解釋一下,每篇文章介紹一個方法。

若需要轉載,請寫明出處,多謝。

/* * Sizzle方法是Sizzle選擇器包的主要入口,jQuery的find方法就是調用該方法獲取匹配的節點 * 該方法主要完成下列任務: * 1、對于單一選擇器,且是ID、Tag、Class三種類型之一,則直接獲取并返回結果 * 2、對于支持querySelectorAll方法的瀏覽器,通過執行querySelectorAll方法獲取并返回匹配的DOM元素 * 3、除上之外則調用select方法獲取并返回匹配的DOM元素 *  *  * @param selector 選擇器字符串 * @param context 執行匹配的最初的上下文(即DOM元素集合)。若context沒有賦值,則取document。 * @param results 已匹配出的部分最終結果。若results沒有賦值,則賦予空數組。 * @param seed 初始集合 */function Sizzle(selector, context, results, seed) {	var match, elem, m, nodeType,	// QSA vars	i, groups, old, nid, newContext, newSelector;	/*	 * preferredDoc = window.document	 * 	 * setDocument方法完成一些初始化工作	 */	if ((context ? context.ownerDocument || context : preferredDoc) !== document) {		setDocument(context);	}	context = context || document;	results = results || [];	/*	 * 若selector不是有效地字符串類型數據,則直接返回results	 */	if (!selector || typeof selector !== "string") {		return results;	}	/*	 * 若context既不是document(nodeType=9),也不是element(nodeType=1),那么就返回空集合	 */	if ((nodeType = context.nodeType) !== 1 && nodeType !== 9) {		return [];	}	// 若當前過濾的是HTML文檔,且沒有設定seed,則執行if內的語句體	if (documentIsHTML && !seed) {		/* 		 * 若選擇器是單一選擇器,且是ID、Tag、Class三種類型之一,則直接獲取并返回結果		 * 		 * rquickExpr = /^(?:#([/w-]+)|(/w+)|/.([/w-]+))$/		 * 上述正則表達式括號內三段依次分別用來判斷是否是ID、TAG、CLASS類型的單一選擇器		 * 上述正則表達式在最外層圓括號內有三個子表達式(即三個圓括號括起來的部分),		 *   分別代表ID、Tag、Class選擇器的值,在下面代碼中,分別體現在match[1]、match[2]、match[3]		 */		if ((match = rquickExpr.exec(selector))) {			// Speed-up: Sizzle("#ID")			// 處理ID類型選擇器,如:#ID			if ((m = match[1])) {				// 若當前上下文是一個document,則執行if內語句體				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						/*						 * 一些老版本的瀏覽器會把name當作ID來處理,						 * 返回不正確的結果,所以需要再一次對比返回節點的ID屬性						 */ 						if (elem.id === m) {							results.push(elem);							return results;						}					} else {						return results;					}				} else {					// Context is not a document					/*					 * contains(context, elem)用來確認獲取的elem是否是當前context對象的子對象					 */					if (context.ownerDocument							&& (elem = context.ownerDocument.getElementById(m))							&& contains(context, elem) && elem.id === m) {						results.push(elem);						return results;					}				}				// Speed-up: Sizzle("TAG")				// 處理Tag類型選擇器,如:SPAN			} else if (match[2]) {				push.apply(results, context.getElementsByTagName(selector));				return results;				// Speed-up: Sizzle(".CLASS")				/*				 * 處理class類型選擇器,如:.class				 * 下面條件判斷分別是:				 * m = match[3]:有效的class類型選擇器				 * support.getElementsByClassName 該選擇器的div支持getElementsByClassName				 * context.getElementsByClassName 當前上下文節點有getElementsByClassName方法				 * 				 */ 							} else if ((m = match[3]) && support.getElementsByClassName					&& context.getElementsByClassName) {				push.apply(results, context.getElementsByClassName(m));				return results;			}		}		// QSA path		/*		 * 若瀏覽器支持querySelectorAll方法且選擇器符合querySelectorAll調用標準,則執行if內語句體		 * 在這里的檢查僅僅是簡單匹配		 * 第一次調用Sizzle時,rbuggyQSA為空		 * 		 * if語句體內對當前context對象的id的賦值與恢復,是用來修正querySelectorAll的一個BUG		 * 該BUG會在某些情況下把當前節點(context)也作為結果返回回來。		 * 具體方法是,在現有的選擇器前加上一個屬性選擇器:[id=XXX],		 * XXX 為context的id,若context本身沒有設置id,則給個默認值expando。		 */				if (support.qsa && (!rbuggyQSA || !rbuggyQSA.test(selector))) {			nid = old = expando;			newContext = context;			// 若context是document,則newSelector取自selector,否則為false			newSelector = nodeType === 9 && selector;			// qSA works strangely on Element-rooted queries			// We can work around this by specifying an extra ID on the			// root			// and working up from there (Thanks to Andrew Dupont for			// the technique)			// IE 8 doesn't work on object elements			if (nodeType === 1 && context.nodeName.toLowerCase() !== "object") {				groups = tokenize(selector);				if ((old = context.getAttribute("id"))) {					/*					 * rescape = /'|///g,					 * 這里將old中的單引號、豎杠、反斜杠前加一個反斜杠					 * old.replace(rescape, "http://$&")代碼中的$&代表匹配項					 */					nid = old.replace(rescape, "http://$&");				} else {					context.setAttribute("id", nid);				}				nid = "[id='" + nid + "'] ";				// 重新組合新的選擇器				i = groups.length;				while (i--) {					groups[i] = nid + toSelector(groups[i]);				}				/*				 * rsibling = new RegExp(whitespace + "*[+~]")				 * rsibling用于判定選擇器是否存在兄弟關系符				 * 若包含+~符號,則取context的父節點作為當前節點				 */				newContext = rsibling.test(selector) && context.parentNode						|| context;				newSelector = groups.join(",");			}			if (newSelector) {				/*				 * 這里之所以需要用try...catch,				 * 是因為jquery所支持的一些選擇器是querySelectorAll所不支持的,				 * 當使用這些選擇器時,querySelectorAll會報非法選擇器,				 * 故需要jquery自身去實現。				 */				try {					// 將querySelectorAll獲取的結果并入results,而后返回resulsts					push.apply(results, newContext							.querySelectorAll(newSelector));					return results;				} catch (qsaError) {				} finally {					if (!old) {						context.removeAttribute("id");					}				}			}		}	}	// All others	// 除上述快捷方式和調用querySelectorAll方式直接獲取結果外,其余都需調用select來獲取結果	/*	 * rtrim = new RegExp("^" + whitespace + "+|((?:^|[^////])(?:////.)*)"	 *			+ whitespace + "+$", "g"),	 * whitespace = "[//x20//t//r//n//f]";	 * 上述rtrim正則表達式的作用是去掉selector兩邊的空白,空白字符由whitespace變量定義	 * rtrim的效果與new RegExp("^" + whitespace + "+|" + whitespace + "+$", "g")相似	 */	return select(selector.replace(rtrim, "$1"), context, results, seed);}

各位朋友,若覺得寫得不錯,幫我頂一下,給點動力,多謝!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
不卡av电影在线观看| 精品少妇一区二区30p| 中文字幕av一区中文字幕天堂| 亚洲欧洲日本专区| 亚洲欧美综合精品久久成人| 亚洲白虎美女被爆操| 美女国内精品自产拍在线播放| 欧美成人一区在线| 国产一区二区三区高清在线观看| 亚洲一区二区三区乱码aⅴ蜜桃女| 欧美第一淫aaasss性| 久久精品国产清自在天天线| 国产成人一区二区三区小说| 精品欧美激情精品一区| 一本色道久久综合狠狠躁篇怎么玩| 亚洲精品720p| 亚洲风情亚aⅴ在线发布| 日本精品一区二区三区在线播放视频| 亚洲第一精品久久忘忧草社区| 97精品一区二区视频在线观看| 日韩有码在线视频| 亚洲大尺度美女在线| 国语自产偷拍精品视频偷| 亚洲美女视频网| 韩剧1988免费观看全集| 在线日韩日本国产亚洲| 亚洲精品视频播放| 亚洲国产精品va在看黑人| 欧美又大又硬又粗bbbbb| 日韩欧美在线中文字幕| 亚洲午夜女主播在线直播| 国产精品久久久久久久av电影| 欧美激情视频网| 成人啪啪免费看| 粗暴蹂躏中文一区二区三区| 136fldh精品导航福利| 最近2019年手机中文字幕| 久久免费成人精品视频| 亚洲国产成人精品久久| 国产精品视频久久| 国产ts人妖一区二区三区| 91人成网站www| 成人国产精品久久久| 亚洲天堂视频在线观看| 欧美做爰性生交视频| 精品亚洲夜色av98在线观看| 久久理论片午夜琪琪电影网| 亚洲国产天堂网精品网站| 色综久久综合桃花网| 成人欧美一区二区三区黑人孕妇| 亚洲一区精品电影| 午夜免费在线观看精品视频| 91牛牛免费视频| 亚洲电影免费观看| 欧美极品少妇xxxxⅹ免费视频| 米奇精品一区二区三区在线观看| 91免费看片在线| 国产精品永久在线| 亚洲欧美在线免费观看| 欧美一级高清免费播放| 97免费中文视频在线观看| 久久精品国产99国产精品澳门| 欧美激情综合色| 夜夜狂射影院欧美极品| 亚洲成人av资源网| 亚洲精品美女视频| 成人午夜黄色影院| 亚洲国产日韩精品在线| 亚洲free性xxxx护士白浆| 国产伦精品一区二区三区精品视频| 国产精品日韩欧美| 另类视频在线观看| 欧美性videos高清精品| 久久精品国亚洲| 久久久精品一区二区三区| 青青草一区二区| 午夜精品福利视频| 国产v综合ⅴ日韩v欧美大片| 欧美巨大黑人极品精男| 91久久久久久久久久| 精品国内产的精品视频在线观看| 91久久在线播放| 国语自产精品视频在线看一大j8| 欧美做爰性生交视频| 国产精品永久免费观看| 午夜精品久久久久久久白皮肤| 97人人爽人人喊人人模波多| 色综合老司机第九色激情| 亚洲精品一区二区网址| 国产成人激情视频| 日韩**中文字幕毛片| 尤物精品国产第一福利三区| 91日本视频在线| 92版电视剧仙鹤神针在线观看| 国产精品久久久久久一区二区| 亚洲综合小说区| 国产亚洲一区精品| 羞羞色国产精品| 中文欧美日本在线资源| 久久97久久97精品免视看| 国产日韩欧美中文在线播放| 国产午夜精品视频| 日韩二区三区在线| 国产91精品久久久久久| 久久精品91久久香蕉加勒比| 成人性教育视频在线观看| 国产成人精品日本亚洲专区61| www.欧美精品| 久久99久国产精品黄毛片入口| 国产精品毛片a∨一区二区三区|国| 亚洲第一网中文字幕| 欧美日韩免费在线| 91久久精品一区| 2020国产精品视频| 91chinesevideo永久地址| 日韩欧亚中文在线| 欧美激情精品久久久久久变态| 日韩激情第一页| 色yeye香蕉凹凸一区二区av| 91久久久国产精品| 69国产精品成人在线播放| 日韩网站在线观看| 日韩电影免费在线观看| 亚洲人成77777在线观看网| 欧美国产日韩一区二区在线观看| 欧美日韩亚洲成人| 国产精品揄拍500视频| 欧美精品久久久久久久久| 日韩欧美在线播放| 国产成人精品最新| 欧美电影院免费观看| 91久久在线视频| 久久天堂av综合合色| 国产精品影院在线观看| 欧美裸体视频网站| 91久久久久久| 成人黄色av网站| 亚洲美女久久久| 成人激情免费在线| 尤物精品国产第一福利三区| 正在播放欧美视频| 日韩国产欧美精品在线| 久久久久久久久亚洲| 国产精品福利观看| 91精品久久久久久久久| 欧美激情中文字幕在线| 国产丝袜精品视频| 国产精品aaaa| 秋霞午夜一区二区| 午夜精品一区二区三区av| 国产成人亚洲综合| 国产精品www网站| 成人欧美在线视频| 亚洲欧美中文日韩在线v日本| 国产美女被下药99| 97在线精品国自产拍中文| 久久99热精品这里久久精品| 亚洲国产精品国自产拍av秋霞| 久久久久久久爱| 亚洲天堂男人的天堂| 欧美精品在线网站| 精品欧美一区二区三区| 日韩免费视频在线观看| 国产精品高清网站|