国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

jQuery選擇器源碼解讀(四):tokenize方法的Expr.preFilter

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

Expr.preFilter是tokenize方法中對ATTR、CHILD、PSEUDO三種選擇器進行預處理的方法。具體如下:

Expr.preFilter : {	"ATTR" : function(match) {		/*		 * 完成如下任務:		 * 1、屬性名稱解碼		 * 2、屬性值解碼		 * 3、若判斷符為~=,則在屬性值兩邊加上空格		 * 4、返回最終的mtach對象		 * 		 * match[1]表示屬性名稱,		 * match[1].replace(runescape, funescape):將屬性名稱中的十六進制數解碼成		 *   單字節unicode字符或雙字節unicode字符(中文或其它需要兩個字節表達的文字)		 * 正則表達式的詳細說明,可以參看我的“詳解jQuery選擇器正則表達式”文章		 */		match[1] = match[1].replace(runescape, funescape);		/*		 * 將屬性值解碼		 * match[4]:表示放在單引號或雙引號內的屬性值		 * match[5]: 表示不用引號括起來的屬性值		 */		match[3] = (match[4] || match[5] || "").replace(runescape,				funescape);		/*		 * ~=的意思是單詞匹配,在W3C中對單詞的定義是以空白為不同單詞的分隔符		 * 故此處在match[3]兩邊加上空格后,可以利用indexOf,正確識別出該單詞是否存在		 */		if (match[2] === "~=") {			match[3] = " " + match[3] + " ";		}		/*		 * 返回有用的前四個元素結果		 */		return match.slice(0, 4);	},	"CHILD" : function(match) {		/*		 * 完成如下幾項任務:		 * 1、把命令中child和of-type之前的字符變成小寫字符		 * 2、對于nth開頭的選擇器檢查括號內的數據有效性		 * 3、match[4]和match[5]分別存放xn+b中的x和b,x和b允許是負數		 * 4、返回最終的match對象		 * 		 * match[1]:(only|first|last|nth|nth-last)中的一個		 */		match[1] = match[1].toLowerCase();		/*		 * 對于nth-child、nth-of-type、nth-last-child、nth-last-of-type四種類型括號內需設置有效數據		 * 而其它則括號內不允許有任何數據		 */		if (match[1].slice(0, 3) === "nth") {			/*			 * 若選擇器括號內沒有有效參數,則拋出異常			 * 舉例:若選擇器是nth或nth(abc)則屬于非法選擇器			 */			if (!match[3]) {				Sizzle.error(match[0]);			}			/*			 * 下面先以nth-child()為例介紹一下語法,以便更好的理解下面代碼的作用			 * nth-child允許的幾種使用方式如下:			 * 	 :nth-child(even)			 * 	 :nth-child(odd)			 * 	 :nth-child(3n)			 * 	 :nth-child(+2n+1)			 * 	 :nth-child(2n-1)			 * 下面代碼中賦值號左側的match[4]、match[5]用于分別記錄括號內n前及n后的數值,包括正負號			 * 對于:nth-child(even)和:nth-child(odd)來說,match[4]為空,			 *   所以返回 2 * (match[3] === "even" || match[3] === "odd")的計算結果			 *   因為在js中true=1,false=0,所以(match[3] === "even" || match[3] === "odd")等于1			 *   因此,2 * (match[3] === "even" || match[3] === "odd")的計算結果為2			 * 			 * 等號右側的“+”的作用是強制類型轉換,將之后的字符串轉換成數值類型 			 */			match[4] = +(match[4] ? match[5] + (match[6] || 1)					: 2 * (match[3] === "even" || match[3] === "odd"));			match[5] = +((match[7] + match[8]) || match[3] === "odd");		} else if (match[3]) {			/*			 * 若非nth起頭的其它CHILD類型選擇器帶有括號說明,則拋出異常			 * 這里jQuery并沒有嚴格按照W3C的規則來判定,因為其允許:first-child()的這種形式存在			 * 也就是對于jQuery來說:first-child()等同于:first-child,是合法選擇器			 */			Sizzle.error(match[0]);		}		return match;	},	"PSEUDO" : function(match) {		/*		 * 完成如下任務:		 * 1、獲取偽類中用引號括起來的值		 * 2、對于非引號括起來的值,若存在偽類嵌套,則進一步解析確定當前偽類實際結束位置,		 *  獲取當前偽類的完整字符串和值		 * 3、返回match中的前三項的副本。		 * 		 * unquoted表示括號內非引號括起來的值,		 * 以:eq(2)為例,unquoted=2		 */		var excess, unquoted = !match[5] && match[2];		/*		 * 因為pseudo與child的匹配正則表達式有交集,所以,需要把屬于child的部分忽略掉		 */		if (matchExpr["CHILD"].test(match[0])) {			return null;		}		/*		 * 若括號內的值使用引號(match[3])括起來的,		 * 則將除引號外的值(match[4])賦給match[2]。		 * match[3]表示引號。		 */		if (match[3] && match[4] !== undefined) {			match[2] = match[4];		} else if (unquoted				/*				 * rpseudo.test(unquoted):用來測試unquoted是否包含偽類,				 * 若包含偽類,則說明有可能存在偽類嵌套的可能性,需要進一步對unquoted進行解析				 * 例如: :not(:eq(3))				 */				&& rpseudo.test(unquoted)				&&				/*				 * 獲取unquoted中連續有效地選擇器最后一個字符所在位置				 */				(excess = tokenize(unquoted, true))				&&				/*				 * unquoted.indexOf(")", unquoted.length - excess)				 *   從之前獲得的連續有效地選擇器最后一個字符所在位置之后找到")"所在位置,				 *   通常就在當前位置之后。				 * 再減去unquoted.length,用來獲得match[0]中的有效完整的偽類字符串最后位置,				 *   注意,此時excess是一個負值				 * 				 */				(excess = unquoted.indexOf(")", unquoted.length						- excess)						- unquoted.length)) {			// 獲取有效的完整偽類match[0]和偽類括號內的數據match[2]			match[0] = match[0].slice(0, excess);			match[2] = unquoted.slice(0, excess);		}		// 返回match前三個元素的副本		return match.slice(0, 3);	}}

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 林甸县| 淮安市| 元江| 郁南县| 乌兰县| 册亨县| 连山| 邳州市| 通江县| 白玉县| 苏尼特右旗| 三门峡市| 楚雄市| 南阳市| 沂水县| 安义县| 如皋市| 高陵县| 自贡市| 水城县| 合江县| 车险| 田东县| 乌什县| 铁岭县| 滕州市| 合水县| 内丘县| 瓦房店市| 阳春市| 镇康县| 西畴县| 区。| 延川县| 焉耆| 隆林| 平山县| 万安县| 花莲市| 新和县| 博客|