废话不多说了直接奔入主题了。
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 ),需要去重和pushStack ret = this.pushStack( len > 1 " " : "" ) + selector; return ret;
jQuery.fn.closest( selectors, context )
第二个参数是可选的。函数用于从当前匹配元素开始,逐级向上级选取符合指定表达式的第一个元素,并以jQuery对象的形式返回。
这里的表达式包括:选择器(字符串)、DOM元素(Element)、jQuery对象。
代码中的处理步骤为
1.根据传递的参数先查询出结果保存在pos中。
pos = rneedsContext.test( selectors ) || typeof selectors !== "string" "htmlcode">for ( ; i < l; i++ ) { cur = this[i]; while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { if ( pos "htmlcode">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 ] "htmlcode">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的节点集合r sibling: 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" "htmlcode">//执行相同的过滤或者不过滤的功能 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 "htmlcode">if ( !elem ) { return ( this[0] && this[0].parentNode ) "htmlcode">if ( typeof elem === "string" ) { //在数组jQuery( elem )中搜索指定的值,并返回其索引值 return jQuery.inArray( this[0], jQuery( elem ) ); }
第三个功能:如果object为DOM元素或jQuery对象,则返回该元素(或该jQuery对象中的第一个元素)在当前jQuery对象所匹配的元素中的索引位置。
return jQuery.inArray(elem.jquery "dataintable" style="border-bottom: rgb(170,170,170) 1px solid; text-align: left; border-left: rgb(170,170,170) 1px solid; padding-bottom: 0px; widows: 1; text-transform: none; background-color: rgb(249,249,249); text-indent: 0px; margin: 10px 0px 0px; padding-left: 0px; width: 709px; letter-spacing: normal; padding-right: 0px; border-collapse: collapse; font: 12px Verdana, Arial, 宋体; white-space: normal; color: rgb(0,0,0); border-top: rgb(170,170,170) 1px solid; border-right: rgb(170,170,170) 1px solid; word-spacing: 0px; padding-top: 0px; -webkit-text-stroke-width: 0px">选择器 实例 选取 * $("*") 所有元素 #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 元素免责声明:本站文章均来自网站采集或用户投稿,网站不提供任何软件下载或自行开发的软件! 如有用户或公司发现本站内容信息存在侵权行为,请邮件告知! 858582#qq.com桃源资源网 Design By www.nqtax.com暂无“Jquery 1.9.1源码分析系列(十二)之筛选操作”评论...