jQuery.fn.find( selector )find接受一个参数表达式selector:选择器(字符串)、DOM元素(Element)、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引擎中有分析,详情点击。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对象的形式返回。
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.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)中获取出结果然后在进行后续的过滤。if ( !runtil.test( name ) ) { selector = until;} 其次,如果有选择器,则通过选择器过滤一下先前查找结果retif ( 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 );
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后面再说。 jQuery.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 ) { // 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: 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函数实际上是一个多功能函数的集合。if ( !elem ) { return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;}if ( typeof elem === "string" ) { //在数组jQuery( elem )中搜索指定的值,并返回其索引值 return jQuery.inArray( this[0], jQuery( elem ) );}return jQuery.inArray(elem.jquery ? elem[0] : elem, this );其他的筛选处理就不分析了。看源码即可明白。
| 选择器 | 实例 | 选取 |
|---|---|---|
| * | $("*") | 所有元素 |
| #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> 元素 |
|
版权所有©石家庄振强科技有限公司2024 冀ICP备08103738号-5 网站地图
|