jQuery選擇器源碼解讀(四):tokenize方法的Expr.preFilter
更新時(shí)間:2015年03月31日 10:44:18 作者:mole
這篇文章主要介紹了jQuery選擇器源碼解讀(四):tokenize方法的Expr.preFilter,本文用詳細(xì)的注釋解讀了tokenize方法的Expr.preFilter的實(shí)現(xiàn)源碼,需要的朋友可以參考下
Expr.preFilter是tokenize方法中對ATTR、CHILD、PSEUDO三種選擇器進(jìn)行預(yù)處理的方法。具體如下:
Expr.preFilter : { "ATTR" : function(match) { /* * 完成如下任務(wù): * 1、屬性名稱解碼 * 2、屬性值解碼 * 3、若判斷符為~=,則在屬性值兩邊加上空格 * 4、返回最終的mtach對象 * * match[1]表示屬性名稱, * match[1].replace(runescape, funescape):將屬性名稱中的十六進(jìn)制數(shù)解碼成 * 單字節(jié)unicode字符或雙字節(jié)unicode字符(中文或其它需要兩個字節(jié)表達(dá)的文字) * 正則表達(dá)式的詳細(xì)說明,可以參看我的“詳解jQuery選擇器正則表達(dá)式”文章 */ match[1] = match[1].replace(runescape, funescape); /* * 將屬性值解碼 * match[4]:表示放在單引號或雙引號內(nèi)的屬性值 * match[5]: 表示不用引號括起來的屬性值 */ match[3] = (match[4] || match[5] || "").replace(runescape, funescape); /* * ~=的意思是單詞匹配,在W3C中對單詞的定義是以空白為不同單詞的分隔符 * 故此處在match[3]兩邊加上空格后,可以利用indexOf,正確識別出該單詞是否存在 */ if (match[2] === "~=") { match[3] = " " + match[3] + " "; } /* * 返回有用的前四個元素結(jié)果 */ return match.slice(0, 4); }, "CHILD" : function(match) { /* * 完成如下幾項(xiàng)任務(wù): * 1、把命令中child和of-type之前的字符變成小寫字符 * 2、對于nth開頭的選擇器檢查括號內(nèi)的數(shù)據(jù)有效性 * 3、match[4]和match[5]分別存放xn+b中的x和b,x和b允許是負(fù)數(shù) * 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四種類型括號內(nèi)需設(shè)置有效數(shù)據(jù) * 而其它則括號內(nèi)不允許有任何數(shù)據(jù) */ if (match[1].slice(0, 3) === "nth") { /* * 若選擇器括號內(nèi)沒有有效參數(shù),則拋出異常 * 舉例:若選擇器是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) * 下面代碼中賦值號左側(cè)的match[4]、match[5]用于分別記錄括號內(nèi)n前及n后的數(shù)值,包括正負(fù)號 * 對于:nth-child(even)和:nth-child(odd)來說,match[4]為空, * 所以返回 2 * (match[3] === "even" || match[3] === "odd")的計(jì)算結(jié)果 * 因?yàn)樵趈s中true=1,false=0,所以(match[3] === "even" || match[3] === "odd")等于1 * 因此,2 * (match[3] === "even" || match[3] === "odd")的計(jì)算結(jié)果為2 * * 等號右側(cè)的“+”的作用是強(qiáng)制類型轉(zhuǎn)換,將之后的字符串轉(zhuǎn)換成數(shù)值類型 */ 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并沒有嚴(yán)格按照W3C的規(guī)則來判定,因?yàn)槠湓试S:first-child()的這種形式存在 * 也就是對于jQuery來說:first-child()等同于:first-child,是合法選擇器 */ Sizzle.error(match[0]); } return match; }, "PSEUDO" : function(match) { /* * 完成如下任務(wù): * 1、獲取偽類中用引號括起來的值 * 2、對于非引號括起來的值,若存在偽類嵌套,則進(jìn)一步解析確定當(dāng)前偽類實(shí)際結(jié)束位置, * 獲取當(dāng)前偽類的完整字符串和值 * 3、返回match中的前三項(xiàng)的副本。 * * unquoted表示括號內(nèi)非引號括起來的值, * 以:eq(2)為例,unquoted=2 */ var excess, unquoted = !match[5] && match[2]; /* * 因?yàn)閜seudo與child的匹配正則表達(dá)式有交集,所以,需要把屬于child的部分忽略掉 */ if (matchExpr["CHILD"].test(match[0])) { return null; } /* * 若括號內(nèi)的值使用引號(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是否包含偽類, * 若包含偽類,則說明有可能存在偽類嵌套的可能性,需要進(jìn)一步對unquoted進(jìn)行解析 * 例如: :not(:eq(3)) */ && rpseudo.test(unquoted) && /* * 獲取unquoted中連續(xù)有效地選擇器最后一個字符所在位置 */ (excess = tokenize(unquoted, true)) && /* * unquoted.indexOf(")", unquoted.length - excess) * 從之前獲得的連續(xù)有效地選擇器最后一個字符所在位置之后找到")"所在位置, * 通常就在當(dāng)前位置之后。 * 再減去unquoted.length,用來獲得match[0]中的有效完整的偽類字符串最后位置, * 注意,此時(shí)excess是一個負(fù)值 * */ (excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) { // 獲取有效的完整偽類match[0]和偽類括號內(nèi)的數(shù)據(jù)match[2] match[0] = match[0].slice(0, excess); match[2] = unquoted.slice(0, excess); } // 返回match前三個元素的副本 return match.slice(0, 3); } }
相關(guān)文章
jQuery+CSS實(shí)現(xiàn)的table表格行列轉(zhuǎn)置功能示例
這篇文章主要介紹了jQuery+CSS實(shí)現(xiàn)的table表格行列轉(zhuǎn)置功能,涉及jQuery事件響應(yīng)及頁面元素屬性動態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-01-01jQuery實(shí)現(xiàn)radio第一次點(diǎn)擊選中第二次點(diǎn)擊取消功能
本篇文章主要介紹了jQuery實(shí)現(xiàn)radio第一次點(diǎn)擊選中第二次點(diǎn)擊取消功能的相關(guān)知識,具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-05-05jquery實(shí)現(xiàn)點(diǎn)擊消失的代碼
這篇文章主要介紹了jquery如何實(shí)現(xiàn)點(diǎn)擊消失,需要的朋友可以參考下2014-03-03jQuery+Ajax+js實(shí)現(xiàn)請求json格式數(shù)據(jù)并渲染到html頁面操作示例
這篇文章主要介紹了jQuery+Ajax+js實(shí)現(xiàn)請求json格式數(shù)據(jù)并渲染到html頁面操作,結(jié)合實(shí)例形式分析了jQuery+Ajax請求json格式數(shù)據(jù)并渲染到html頁面相關(guān)步驟與操作技巧,需要的朋友可以參考下2020-06-06