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

首頁 > 語言 > JavaScript > 正文

jQuery選擇器源碼解讀(三):tokenize方法

2024-05-06 16:17:54
字體:
來源:轉載
供稿:網友

這篇文章主要介紹了jQuery選擇器源碼解讀(三):tokenize方法,本文用詳細的注釋解讀了tokenize方法的實現源碼,需要的朋友可以參考下

 

 
  1. /* 
  2. * tokenize方法是選擇器解析的核心函數,它將選擇器轉換成兩級數組groups 
  3. * 舉例: 
  4. * 若選擇器為“div.class,span”,則解析后的結果為: 
  5. * group[0][0] = {type:'TAG',value:'div',matches:match} 
  6. * group[0][1] = {type:'CLASS',value:'.class',matches:match} 
  7. * group[1][0] = {type:'TAG',value:'span',matches:match} 
  8. * 由上述結果可以看出,groups的每一個元素以逗號分隔的選擇器塊的解析結果, 
  9. * 另外,上述結果中的matches等于模式匹配的結果,由于在此不方便寫清楚, 
  10. * 故只把代碼matches:match寫在這里。 
  11.  
  12. * tokenize方法完成如下兩個主要任務: 
  13. * 1、解析選擇器 
  14. * 2、將解析結果存入緩存中,以備后用 
  15.  
  16.  
  17. * @param selector 待解析的選擇器字符串 
  18. * @param parseOnly 為true時,說明本次調用是匹配子選擇器 
  19. * 舉個例子:若初始選擇器為"div:not(.class:not(:eq(4))):eq(3)" 
  20. * 代碼首先匹配出TAG選擇器div, 
  21. * 之后匹配出的pseudo選擇器字符串是:not(.class:not(:eq(4))):eq(3), 
  22. * 代碼會把“.class:not(:eq(4))):eq(3”作為not的括號內的值進一步進行解析, 
  23. * 此時代碼在調用tokenize解析時,parseOnly參數會傳入true. 
  24. */ 
  25. function tokenize(selector, parseOnly) { 
  26. var matched, match, tokens, type, soFar, groups, preFilters,  
  27. // 獲取緩存中的結果 
  28. cached = tokenCache[selector + " "]; 
  29.  
  30. /* 
  31. * 若緩存中有selector對應的解析結果 
  32. * 則執行if中語句體 
  33. */ 
  34. if (cached) { 
  35. // 若是對初始選擇器解析(parseOnly!=true),則返回緩存結果, 
  36. // 若不是,則返回0 
  37. return parseOnly ? 0 : cached.slice(0); 
  38.  
  39. /* 
  40. * 由于字符串在javascript中不是作為對象來處理的, 
  41. * 所以通過賦值,代碼就自動復制了一個新字符串給了soFar, 
  42. * 這樣,對soFar的任何處理都不會影響selector的原有數據 
  43. */ 
  44. soFar = selector; 
  45. groups = []; 
  46. // 此處賦值,僅僅用于減少后續代碼字數,縮短執行路徑 
  47. preFilters = Expr.preFilter; 
  48.  
  49. while (soFar) { 
  50.  
  51. // Comma and first run 
  52. /* 
  53. * rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*") 
  54. * rcomma用來判定是否存在多個選擇器塊,即用逗號隔開的多個并列的選擇器 
  55.  
  56. * 下面條件判定依次為: 
  57. * !matched:若是第一次執行循環體,則為true;否則為false。 
  58. * 這里matched即作為是否第一次執行循環體的標識, 
  59. * 也作為本次循環中soFar是否以非法字符串(即非合法單一選擇器)開頭的標志。 
  60. * (match = rcomma.exec(soFar):獲取符合rcomma的匹配項 
  61. */ 
  62. if (!matched || (match = rcomma.exec(soFar))) { 
  63. if (match) { 
  64. // Don't consume trailing commas as valid 
  65. /* 
  66. * 剔除掉第一個逗號及之前的所有字符 
  67. * 舉個例子: 
  68. * 若初始選擇器為:"div.news,span.closed", 
  69. * 在解析過程中,首先由后續代碼解析完畢div.news,剩下",span.closed" 
  70. * 在循環體內執行到這里時,將逗號及之前之后連續的空白(match[0])刪除掉, 
  71. * 使soFar變成"span.closed",繼續執行解析過程 
  72.  
  73. * 在這里,若初始選擇器的最后一個非空白字符是逗號, 
  74. * 那么執行下面代碼時soFar不變,即soFar.slice(match[0].length)返回空字符串, 
  75. * 故最終返回的是||后面的soFar 
  76. */ 
  77. soFar = soFar.slice(match[0].length) || soFar; 
  78.  
  79. /* 
  80. * 在第一次執行循環體或者遇到逗號分割符時,將tokens賦值為一個空數組, 
  81. * 同時壓入groups數組 
  82. */ 
  83. groups.push(tokens = []); 
  84.  
  85. matched = false
  86.  
  87. // Combinators 
  88. /* 
  89. * rcombinators = new RegExp( 
  90. * "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*"), 
  91. * rcombinators用來匹配四種關系符,即>+~和空白 
  92.  
  93. * 若soFar中是以關系符開始的,則執行if內的語句體 
  94. */ 
  95. if ((match = rcombinators.exec(soFar))) { 
  96. /* 
  97. * 將match[0]移除match數組,同時將它賦予matched 
  98. * 若原本關系符兩邊帶有空格,則此時match[0]與matched是不相等的 
  99. * 舉個例子: 
  100. * 若soFar = " + .div"; 
  101. * 執行match = rcombinators.exec(soFar)后, 
  102. * match[0] = " + ",而match[1]="+"; 
  103. * 執行完matched = match.shift()后, 
  104. * matched=" + ",而match[0]="+"; 
  105. */ 
  106. matched = match.shift(); 
  107. // 將匹配結果壓入tokens數組中 
  108. tokens.push({ 
  109. value : matched, 
  110. // Cast descendant combinators to space 
  111. /* 
  112. * rtrim = new RegExp("^" + whitespace + "+|((?:^|[^////])(?:////.)*)" 
  113. * + whitespace + "+$", "g"), 
  114. * whitespace = "[//x20//t//r//n//f]"; 
  115.  
  116. * 下面match[0].replace(rtrim, " ")的作用是將match[0]左右兩邊的空白替換為空格 
  117. * 但是由于其上的match.shift的作用,match[0]已經是兩邊不帶空白的字符串了, 
  118. * 故此出的替換是沒有用途的代碼 
  119. */ 
  120. type : match[0].replace(rtrim, " "
  121. }); 
  122.  
  123. // 將關系符之后的字符串賦予soFar,繼續解析 
  124. soFar = soFar.slice(matched.length); 
  125.  
  126. // Filters 
  127. /* 
  128. * 下面通過for語句對soFar逐一匹配ID、TAG、CLASS、CHILD、ATTR、PSEUDO類型的選擇器 
  129. * 若匹配到了,則先調用該類型選擇器對應的預過濾函數, 
  130. * 然后,將結果壓入tokens數組,繼續本次循環。 
  131. */ 
  132. for (type in Expr.filter) { 
  133. /* 
  134. * match = matchExpr[type].exec(soFar):對soFar調用type類型的正則表達式對soFar進行匹配, 
  135. * 并將匹配結果賦予match。若未匹配到數據,則match為undefined。 
  136. * !preFilters[type]:若不存在type類型的預過濾函數,則為true 
  137. * match = preFilters[type](match):執行預過濾,并將結果返回給match 
  138.  
  139. */ 
  140. if ((match = matchExpr[type].exec(soFar)) 
  141. && (!preFilters[type] || (match = preFilters[type] 
  142. (match)))) { 
  143. // 將match[0]移除match數組,同時將它賦予matched 
  144. matched = match.shift(); 
  145. // 將匹配結果壓入tokens數組中 
  146. tokens.push({ 
  147. value : matched, 
  148. type : type, 
  149. matches : match 
  150. }); 
  151. // 將匹配結果之后的字符串賦予soFar,繼續解析 
  152. soFar = soFar.slice(matched.length); 
  153.  
  154. /* 
  155. * 若matched==false, 
  156. * 則說明本次循環沒有有效的選擇器(包括關系符和id、class等類型選擇器) 
  157. * 因此,解析到當前位置遺留下來的soFar是非法的選擇器字符串 
  158. * 跳出while循環體 
  159. */ 
  160. if (!matched) { 
  161. break
  162.  
  163. // Return the length of the invalid excess 
  164. // if we're just parsing 
  165. // Otherwise, throw an error or return tokens 
  166. /* 
  167. * 若不是對初始選擇器字符串進行解析(!parseOnly==true), 
  168. * 則返回soFar.length,此時的soFar.length代表連續有效的選擇器最終位置, 
  169. * 后續文章將以實例進行說明 
  170. * 若是對初始選擇器字符串進行解析,則看soFar是否還有字符, 
  171. * 若是,則執行Sizzle.error(selector)拋出異常; 
  172. * 若不是,則執行tokenCache(selector, groups).slice(0)將結果壓入緩存,并返回結果的副本。 
  173. */ 
  174. return parseOnly ? soFar.length : soFar ? Sizzle.error(selector) : 
  175. // Cache the tokens 
  176. tokenCache(selector, groups).slice(0); 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美性生活大片免费观看网址| 国产亚洲精品久久久优势| 欧美日韩性生活视频| 日韩视频免费在线观看| 国产精品影片在线观看| 国产精品一区二区久久精品| 日本精品va在线观看| 日韩电视剧在线观看免费网站| 欧美性猛交xxxx富婆弯腰| 国模视频一区二区三区| 97国产精品人人爽人人做| 国产中文字幕亚洲| 91亚洲国产成人久久精品网站| 成人网中文字幕| 亚洲欧美制服另类日韩| 日韩视频免费中文字幕| 欧美精品久久久久久久免费观看| 亚洲最大福利视频网站| 久久香蕉国产线看观看av| 麻豆一区二区在线观看| 中文字幕精品av| 亚洲最大av网站| 亚洲精品在线视频| 欧美日韩裸体免费视频| 久久久久久久久爱| 77777亚洲午夜久久多人| 久久精品99久久久久久久久| 成人精品久久一区二区三区| 97婷婷涩涩精品一区| 秋霞午夜一区二区| 亚洲国产成人精品久久久国产成人一区| 久久久久一本一区二区青青蜜月| 亚洲最大福利视频| 亚洲美女www午夜| 精品成人av一区| 久久99国产精品久久久久久久久| 日日骚久久av| 在线观看日韩专区| 92裸体在线视频网站| 国外成人在线视频| 欧美在线激情网| 中文字幕在线精品| 精品国产1区2区| 成人乱人伦精品视频在线观看| 欧美激情精品久久久久久| 亚洲成av人乱码色午夜| 中文字幕亚洲无线码在线一区| 欧美与欧洲交xxxx免费观看| 麻豆乱码国产一区二区三区| 日韩成人在线视频观看| 日韩av免费在线观看| 亚洲精品suv精品一区二区| 国产精品视频永久免费播放| 欧美色另类天堂2015| 欧美怡红院视频一区二区三区| 国产69精品99久久久久久宅男| 成人综合网网址| 国产精品视频xxx| 国产精品网红直播| 这里只有精品在线播放| 国产高清在线不卡| 亚洲欧美制服第一页| 国产精品18久久久久久麻辣| 亚洲欧洲在线看| 久久夜色精品亚洲噜噜国产mv| 亚洲a∨日韩av高清在线观看| 欧美www视频在线观看| 亚洲成avwww人| 97视频免费在线看| 中文字幕免费精品一区高清| 欧美大秀在线观看| 国产91精品久久久| 久久精品2019中文字幕| 国产成人avxxxxx在线看| 欧美最猛性xxxxx亚洲精品| 欧美福利视频在线观看| 91免费国产网站| 欧美孕妇毛茸茸xxxx| 欧美日韩综合视频网址| 日韩av免费一区| 福利一区视频在线观看| 久久精品免费播放| 日韩欧美在线视频日韩欧美在线视频| 亚洲第一页自拍| 欧美激情一区二区三区成人| 亚洲社区在线观看| 欧美激情视频免费观看| 国产精品夜色7777狼人| 成人动漫网站在线观看| 欧美日韩国产页| 国产91在线高潮白浆在线观看| 久久久久久亚洲精品| 久久久精品中文字幕| 亚洲毛茸茸少妇高潮呻吟| 国产精品高潮粉嫩av| 亚洲精品综合久久中文字幕| 国产一区二区视频在线观看| 成人国产精品av| 欧美大片欧美激情性色a∨久久| 麻豆一区二区在线观看| 北条麻妃久久精品| 国产精品一区久久| 日韩中文字在线| 一区二区三区天堂av| 久久久精品视频成人| 欧美日韩国产va另类| 久久久成人av| 最近2019年好看中文字幕视频| 不卡av电影院| 亚洲男人天堂久| 欧美电影免费观看电视剧大全| 青青精品视频播放| 在线看日韩欧美| 欧美日本精品在线| 国外成人在线播放| 欧美激情精品久久久久久久变态| 久久综合五月天| 国内外成人免费激情在线视频网站| 国产精品欧美日韩久久| 国产精品com| 久久久精品一区| 日韩高清欧美高清| 91精品国产91久久久久久| 国产欧美精品一区二区三区介绍| 久久久精品欧美| 国产一区二区三区四区福利| 亚洲国产精品成人精品| 亚洲第一页在线| 日韩精品免费综合视频在线播放| 在线视频精品一| 国产精品大陆在线观看| 韩国美女主播一区| 992tv成人免费影院| 欧美激情免费视频| 在线播放日韩精品| 一二美女精品欧洲| 欧美在线视频播放| 午夜精品一区二区三区av| 91精品久久久久久久久久久久久| 久久免费视频网站| 亚洲影院色在线观看免费| 欧美成人网在线| 亚洲欧美一区二区三区久久| 久久久精品久久久久| yw.139尤物在线精品视频| 91av视频在线播放| 欧美福利视频在线观看| 日韩黄色av网站| 欧美日韩成人精品| 2020欧美日韩在线视频| 欧美日韩另类视频| 国产精品欧美一区二区三区奶水| 欧美日韩激情视频| 亚洲国产精品成人va在线观看| 国产成人精品在线视频| 日韩免费视频在线观看| 色天天综合狠狠色| 正在播放亚洲1区| 91精品国产一区| 一区二区三区美女xx视频| 久久久国产成人精品| 亚洲视频777| 日韩一区二区三区xxxx| 欧美中文字幕在线播放|