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

首頁 > 語言 > JavaScript > 正文

Jquery 1.9.1源碼分析系列(十二)之篩選操作

2024-05-06 16:25:43
字體:
來源:轉載
供稿:網友
這篇文章主要介紹了Jquery 1.9.1源碼分析系列(十二)之篩選操作的相關資料,需要的朋友可以參考下
 

廢話不多說了直接奔入主題了。

jQuery.fn.find( selector )

  find接受一個參數表達式selector:選擇器(字符串)、DOM元素(Element)、jQuery對象。分兩種情況處理:

  第一種,如果傳入的參數是非字符串,則先通過jQuery選擇器將selector查找出來,然后過濾出包含于當前jQuery對象所匹配的元素的節點。

if ( typeof selector !== "string" ) { self = this; return this.pushStack( jQuery( selector ).filter(function() {  for ( i = 0; i < len; i++ ) {   if ( jQuery.contains( self[ i ], this ) ) {    return true;   }  } }) );}

可以看出過濾條件中jQuery.contains( self[ i ], this )是關鍵,該函數使用的是Sizzle選擇器中的函數,在Sizzle引擎中有分析,詳情點擊。

第二種,如果選擇器是字符串,調用jQuery.find (= Sizzle)直接處理

ret = [];for ( i = 0; i < len; i++ ) { //第二個參數是表示context jQuery.find( selector, this[ i ], ret );}//$( selector, context )變成$( context ).find( selector ),需要去重和pushStackret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );ret.selector = ( this.selector ? this.selector + " " : "" ) + selector;return ret;
jQuery.fn.closest( selectors, context )

  第二個參數是可選的。函數用于從當前匹配元素開始,逐級向上級選取符合指定表達式的第一個元素,并以jQuery對象的形式返回。

  這里的表達式包括:選擇器(字符串)、DOM元素(Element)、jQuery對象。

  代碼中的處理步驟為

  1.根據傳遞的參數先查詢出結果保存在pos中。

pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?jQuery( selectors, context || this.context ) :0;

  2.遍歷當前jQuery對象的每一個元素,從這個元素開始,逐級向上級選取符合指定表達式的第一個祖先元素。

for ( ; i < l; i++ ) { cur = this[i]; while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) {  if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {   ret.push( cur );   break;  }  cur = cur.parentNode; }}return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );

  parents() 和 .closest() 方法類似,它們都沿 DOM 樹向上遍歷。但區別也很大closest找到第一個符合條件就截止,parents是找到所有符合條件的集合。

jQuery.fn. parent/ parents/ parentsUntil/ next/ prev/ nextAll/ prevAll/ nextUntil/ prevUntil/ siblings/ children/ contents詳解

  以上幾組篩選被放在一起處理,源碼如下

jQuery.each({  parent: function( elem ) {…},  parents: function( elem ) {…},  parentsUntil: function( elem, i, until ) {…},  next: function( elem ) {…},  prev: function( elem ) {…},  nextAll: function( elem ) {…},  prevAll: function( elem ) {…},  nextUntil: function( elem, i, until ) {…},  prevUntil: function( elem, i, until ) {…},  siblings: function( elem ) {…},  children: function( elem ) {…},  contents: function( elem ) {…} }, function( name, fn ) {  jQuery.fn[ name ] = function( until, selector ) {   var ret = jQuery.map( this, fn, until );   //過濾   ...   return this.pushStack( ret );  }; });

  可以看出,這幾個篩選步驟一致。都是先通過map函數把當前jQuery對象每個匹配的元素代入相應的匹配函數(fn)中獲取出結果然后在進行后續的過濾。

  我們先看一下后面的過濾(已經通過jQuery.map( this, fn, until )獲取到了備選種子ret)
  首先,并不是所有的篩選函數都有until這個參數,只有以Until結尾的幾個篩選才需要這個參數,其他的篩選只有selector這個參數。

if ( !runtil.test( name ) ) { selector = until;}

  其次,如果有選擇器,則通過選擇器過濾一下先前查找結果ret

if ( selector && typeof selector === "string" ) { ret = jQuery.filter( selector, ret );}

  然后,guaranteedUnique里面的幾種篩選條件(children/contents/next/prev)在當前jQuery對象所匹配的元素個數有多個的時候,通過每個匹配元素獲取到的結果保存在結果集ret中,且不需要去重。其他篩選是要去重的。點擊查看jQuery.unique方法詳解

ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret;

  另外,還需要處理的特殊情況是: 如果當前jQuery對象所匹配的元素有多個,則使用parents /prevUntil /prevAll這三種篩選的結果需要倒序排列。需要倒序的原因:jQuery.unique使用的是Sizzle引擎中的排序函數Sizzle .uniqueSort,這個排序函數會根據文檔最頂層對象到最底層的方式排列。

if ( this.length > 1 && rparentsprev.test( name ) ) { ret = ret.reverse();}

  最后,返回包裹后的結果

return this.pushStack( ret ); 

  上面說了主題的框架結構,下面說一下這一組篩選器匹配函數里面用到的兩個函數jQuery.dir和jQuery. sibling,直接上源碼
//從當前元素elem指定的dir對應的節點開始一直查找dir,并將這些節點保存在matched中,直到循環終止。注意:結果中不包含elem節點

dir: function( elem, dir, until ) { var matched = [], cur = elem[ dir ]; while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {  if ( cur.nodeType === 1 ) {   matched.push( cur );  }  cur = cur[dir]; } return matched;},//獲取節點n及其兄弟節點中非elem的節點集合rsibling: function( n, elem ) { var r = []; for ( ; n; n = n.nextSibling ) {  if ( n.nodeType === 1 && n !== elem ) {   r.push( n );  } } return r;}//找到當前元素cur的下一個dir為止function sibling( cur, dir ) {  do {   cur = cur[ dir ];  } while ( cur && cur.nodeType !== 1 );  return cur; } 
jQuery.fn.add( selector, context )和jQuery.fn. addBack( selector )

  add函數是向當前匹配元素中添加符合指定表達式的元素,并以jQuery對象的形式返回。add可以接收包括:選擇器(字符串)、HTML內容(字符串)、DOM元素(Element)、jQuery對象。處理比較簡單,直接上源碼

add: function( selector, context ) { var set = typeof selector === "string" ?   jQuery( selector, context ) :   jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),  //把selector表達式獲取的結果集拼接到當前對象上  all = jQuery.merge( this.get(), set ); //返回新的拼接結果 return this.pushStack( jQuery.unique(all) );}  jQuery.fn.add和jQuery.fn.not相對應。jQuery.fn.not后面再說?! Query.fn.addBack將之前匹配的元素加入到當前匹配的元素中,并以新的jQuery對象的形式返回。addBack: function( selector ) { return this.add( selector == null ?  this.prevObject : this.prevObject.filter(selector)  );}jQuery.fn.andSelf = jQuery.fn.addBack;  jQuery.fn.not( selector )和jQuery.fn.filter( selector )not: function( selector ) { return this.pushStack( winnow(this, selector, false) );}filter: function( selector ) { return this.pushStack( winnow(this, selector, true) );},

  not和filter都是操作本身的集合,not是過濾掉本身集合中滿足過濾條件selector的項,留下其他項。而filter是留下滿足過濾條件selector的項。

  關鍵是function winnow( elements, qualifier, keep )函數。這個函數的功能是執行相同的過濾或者不過濾的功能。過濾條件qualifier有三種:函數、DOM節點、字符串。keep:true表示保留滿足過濾條件的項,false表示保留不滿足過濾條件的項。

winnow的源碼注釋如下

//執行相同的過濾或者不過濾的功能function winnow( elements, qualifier, keep ) { // Can't pass null or undefined to indexOf in Firefox 4 // Set to 0 to skip string check qualifier = qualifier || 0; //如果過濾條件是函數,則通過過濾函數過濾 if ( jQuery.isFunction( qualifier ) ) {  return jQuery.grep(elements, function( elem, i ) {   var retVal = !!qualifier.call( elem, i, elem );   return retVal === keep;  }); //如果過濾條件是DOM相關類型,通過比較節點是否相同來過濾 } else if ( qualifier.nodeType ) {  return jQuery.grep(elements, function( elem ) {   return ( elem === qualifier ) === keep;  }); //如果過濾條件是字符串 } else if ( typeof qualifier === "string" ) {  //過濾出elements中的節點元素  var filtered = jQuery.grep(elements, function( elem ) {   return elem.nodeType === 1;  });  // 其中isSimple = /^.[^:#/[/.,]*$/  if ( isSimple.test( qualifier ) ) {   return jQuery.filter(qualifier, filtered, !keep);  } else {   //查找filtered中滿足篩選條件qualifier的節點   qualifier = jQuery.filter( qualifier, filtered );  } } //過濾出elements中滿足過濾條件的元素 return jQuery.grep(elements, function( elem ) {  return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; });}

  其中用到jQuery.grep,grep詳解點擊這里。

  jQuery.filter( expr, elems, not )這個低級api專門用來處理jQuery.fn.filter中過濾條件為字符串的情況。

jQuery.filter: function( expr, elems, not ) { if ( not ) {  expr = ":not(" + expr + ")"; } //其中matchesSelector和matches是Sizzle中的函數。matchesSelector是判斷單個元素elem是否滿足表達式expr,matches是查找元素集合elems中滿足表達式expr的項 return elems.length === 1 ?  jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] :  jQuery.find.matches(expr, elems);},jQuery.fn.index( elem )

  index函數實際上是一個多功能函數的集合。

  第一個功能:不傳遞elem參數,則表示取當前jQuery對象(jQuery對象的第一個元素)在其所有同輩元素中的位置。

if ( !elem ) { return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;}

  第二個功能:如果參數為String類型則將其視作選擇器,返回當前元素在選擇器所匹配的元素中的索引位置。如果該選擇器不匹配任何元素或者當前元素不在匹配到的元素內,則返回-1。

if ( typeof elem === "string" ) { //在數組jQuery( elem )中搜索指定的值,并返回其索引值 return jQuery.inArray( this[0], jQuery( elem ) );}

  第三個功能:如果object為DOM元素或jQuery對象,則返回該元素(或該jQuery對象中的第一個元素)在當前jQuery對象所匹配的元素中的索引位置。

return jQuery.inArray(elem.jquery ? elem[0] : elem, this ); 

  其他的篩選處理就不分析了。看源碼即可明白。

jquery選擇器

 

選擇器 實例 選取
* $("*") 所有元素
#id $("#lastname") id="lastname" 的元素
.class $(".intro") 所有 class="intro" 的元素
element $("p") 所有 <p> 元素
.class.class $(".intro.demo") 所有 class="intro" 且 class="demo" 的元素
     
:first $("p:first") 第一個 <p> 元素
:last $("p:last") 最后一個 <p> 元素
:even $("tr:even") 所有偶數 <tr> 元素
:odd $("tr:odd") 所有奇數 <tr> 元素
     
:eq(index) $("ul li:eq(3)") 列表中的第四個元素(index 從 0 開始)
:gt(no) $("ul li:gt(3)") 列出 index 大于 3 的元素
:lt(no) $("ul li:lt(3)") 列出 index 小于 3 的元素
:not(selector) $("input:not(:empty)") 所有不為空的 input 元素
     
:header $(":header") 所有標題元素 <h1> - <h6>
:animated   所有動畫元素
     
:contains(text) $(":contains('W3School')") 包含指定字符串的所有元素
:empty $(":empty") 無子(元素)節點的所有元素
:hidden $("p:hidden") 所有隱藏的 <p> 元素
:visible $("table:visible") 所有可見的表格
     
s1,s2,s3 $("th,td,.intro") 所有帶有匹配選擇的元素
     
[attribute] $("[href]") 所有帶有 href 屬性的元素
[attribute=value] $("[href='#']") 所有 href 屬性的值等于 "#" 的元素
[attribute!=value] $("[href!='#']") 所有 href 屬性的值不等于 "#" 的元素
[attribute$=value] $("[href$='.jpg']") 所有 href 屬性的值包含以 ".jpg" 結尾的元素
     
:input $(":input") 所有 <input> 元素
:text $(":text") 所有 type="text" 的 <input> 元素
:password $(":password") 所有 type="password" 的 <input> 元素
:radio $(":radio") 所有 type="radio" 的 <input> 元素
:checkbox $(":checkbox") 所有 type="checkbox" 的 <input> 元素
:submit $(":submit") 所有 type="submit" 的 <input> 元素
:reset $(":reset") 所有 type="reset" 的 <input> 元素
:button $(":button") 所有 type="button" 的 <input> 元素
:image $(":image") 所有 type="image" 的 <input> 元素
:file $(":file") 所有 type="file" 的 <input> 元素
     
:enabled $(":enabled") 所有激活的 input 元素
:disabled $(":disabled") 所有禁用的 input 元素
:selected $(":selected") 所有被選取的 input 元素
:checked $(":checked") 所有被選中的 input 元素


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表

圖片精選

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲欧美成人精品| 亚洲一级免费视频| 亚洲欧洲国产伦综合| 国产aaa精品| 国产欧美亚洲精品| 正在播放国产一区| 日韩电影网在线| 久久久免费高清电视剧观看| 精品一区二区亚洲| 国产日韩精品综合网站| 亚洲欧美日韩精品久久奇米色影视| 久久综合国产精品台湾中文娱乐网| 亚洲日本欧美日韩高观看| 91精品国产成人www| 高清欧美电影在线| 另类美女黄大片| 性欧美办公室18xxxxhd| 欧美日韩精品国产| 亚洲影影院av| 九九热r在线视频精品| 亚洲色图综合网| 欧美小视频在线观看| 91在线色戒在线| 狠狠做深爱婷婷久久综合一区| 国产精品一区二区三| 久久久之久亚州精品露出| 91欧美精品成人综合在线观看| 国产做受高潮69| 久久精品国产2020观看福利| 最近日韩中文字幕中文| 久久全球大尺度高清视频| 亚洲成色999久久网站| 日韩国产欧美精品一区二区三区| 日韩av在线免费播放| 97**国产露脸精品国产| 成人黄色免费片| 久久亚洲精品中文字幕冲田杏梨| 国产97在线|日韩| 精品久久香蕉国产线看观看gif| 欧美成人精品三级在线观看| 日韩精品视频在线| 亚洲国产欧美一区二区三区久久| 欧美国产日韩二区| 91国产视频在线| 日韩av影院在线观看| 国产精品久久久久久久久久久不卡| 亚洲成人网在线观看| 在线视频国产日韩| 欧美劲爆第一页| 欧美做受高潮电影o| 亚洲综合精品一区二区| 亚洲精品成人网| 91在线直播亚洲| 亚洲国产小视频| 美女久久久久久久| 久久国产精品网站| 91香蕉嫩草神马影院在线观看| 欧美精品久久久久久久| 欧美精品xxx| 欧洲午夜精品久久久| 久久精品中文字幕电影| 久久在线视频在线| 亚洲日本aⅴ片在线观看香蕉| 97在线视频一区| 午夜精品一区二区三区在线| 欧美激情一区二区久久久| 亚洲国产免费av| 91精品国产91久久| 国产在线观看精品一区二区三区| 亚洲美女在线看| 亚洲精品国产免费| 亚洲国产精品一区二区三区| 日韩电视剧在线观看免费网站| 亚洲日本中文字幕| 日韩欧美亚洲一二三区| 亚洲人永久免费| 亚洲第一精品自拍| 国产精品av在线| 欧美午夜视频一区二区| 欧美日韩一区二区三区| 中文字幕欧美日韩精品| 欧美一级在线亚洲天堂| 在线免费看av不卡| 亚洲天堂av电影| 亚洲激情视频在线观看| 国产亚洲精品美女| 国模精品一区二区三区色天香| 欧洲一区二区视频| 久久久久九九九九| 亚洲国产日韩欧美在线图片| 日韩一区二区福利| 性色av一区二区咪爱| 亚洲xxxxx性| 欧美丰满老妇厨房牲生活| 亚洲国产一区二区三区在线观看| 久久久精品国产亚洲| 久久久999国产| 亚洲春色另类小说| 国产亚洲精品高潮| 久久久久久久一区二区| 91在线视频导航| 91精品国产综合久久久久久久久| 亚洲第一区中文字幕| 久久久999精品免费| 色婷婷综合成人av| 国产精品v日韩精品| 欧美在线视频在线播放完整版免费观看| 亚洲网站视频福利| 国产欧美日韩精品丝袜高跟鞋| 九九精品在线观看| 92国产精品久久久久首页| 国产91色在线播放| 亚洲欧美在线免费观看| 国内伊人久久久久久网站视频| 欧美视频国产精品| 日韩电影在线观看免费| 日本精品一区二区三区在线| 在线观看国产精品91| 欧美韩日一区二区| 91久久精品日日躁夜夜躁国产| 日韩成人激情在线| 久久影院资源网| 日本精品性网站在线观看| 国产精品99蜜臀久久不卡二区| 久久久在线视频| 精品久久中文字幕| 亚洲国产精品大全| 成人写真视频福利网| 欧美老女人在线视频| 欧美激情在线观看视频| 亚洲美女视频网| 超碰日本道色综合久久综合| 精品久久久久久久久久| 中文字幕亚洲综合| 7777精品视频| 亚洲高清av在线| 国产一区二区三区高清在线观看| 久久久精品国产一区二区| 日韩中文字幕av| 成人福利在线观看| 亚洲v日韩v综合v精品v| 国产成人av在线播放| 日韩在线免费高清视频| 欧美床上激情在线观看| 亚洲国产精品久久久久秋霞不卡| 国产一区二区三区直播精品电影| 成人www视频在线观看| 久久成人精品电影| 国产成人亚洲综合91精品| 久久久久久尹人网香蕉| 日韩大片在线观看视频| 国产午夜精品全部视频在线播放| 国产精品成人一区| 尤物99国产成人精品视频| 国产亚洲欧美另类中文| 久久久www成人免费精品张筱雨| 欧美日韩在线观看视频小说| 国产成人aa精品一区在线播放| 精品久久久久久国产91| 亚洲午夜色婷婷在线| 欧美激情视频一区二区三区不卡| 欧美精品videos性欧美| 色综合天天狠天天透天天伊人| 亚洲精品v欧美精品v日韩精品|