traversing.js源码
提供查询、过滤方法
traversing.js
// dir.js define([ "../../core" ],function(jQuery){ return function(elem,dir,until){ var matched=[], truncate=until!==undefined; while ( ( elem=elem[dir] ) && elem.nodeType!==9 ){ if ( elem.nodeType===1 ) { if ( truncate && jQuery(elem).is(until) ){ break; } matched.push(elem); } } return matched; }; }); // siblings.js define(function(){ return function(n,elem){ var matched=[]; for ( ; n; n=n.nextSibling ){ if ( n.nodeType===1 && n!==elem ){ matched.push(n); } } return matched; }; }); // traversing.js define( [ "./core", "./var/indexOf", // dir(elem,dir,until) dir为待获取元素的elem的位置关系,until选择器找到该元素时,查询终止 "./traversing/var/dir", // siblings(n,elem) 遍历获取n的兄弟节点,排除elem "./traversing/var/siblings", // jQuery.expr.match.needsContext "+"、":odd"等需要查询的父节点 "./traversing/var/rneedsContext", "./core/init", "./traversing/findFilter", "./selector" ],function(jQuery,indexOf,dir,siblings,rneedsContext){ var rparentsprev=/^(?:parents|prev(?:Until|All))/, // Methods guaranteed to produce a unique set when starting from a unique set guaranteedUnique={ children:true, contents:true, next:true, prev:true }; jQuery.fn.extend({ // 查找子节点 has:function(target){ var targets=jQuery(target,this), l=targets.length; return this.filter(function(){ var i=0; for ( ; i<l; i++ ){ if ( jQuery.contains(this,targets[i]) ){ return true; } } }); }, // 向上获取所有匹配selectors的节点,selector不能使":odd"、":first"、"+"等带有层级关系 // 在文档查询所有selectors,滤除不是当前元素父节点的元素 closest:function(selectors,context){ var cur, i=0, l=this.length, matched=[], targets=typeof selectors!=="string" && jQuery(selectors); if ( !rneedsContext.test(selectors) ){ for ( ; i<l; i++ ){ for ( cur=this[i]; cur && cur!==context; cur=cur.parentNode ){ if ( cur.nodeType<11 && ( targets ? targets.index(cur)>-1 : cur.nodeType===1 && jQuery.find.matchesSelector(cur,selectors) ) ){ matched.push(cur); break; } } } } return this.pushStack(matched.length>1 ? jQuery.uniqueSort(matched) : matched); }, // 获取当前元素在传参选择器俘获元素中的index值,或传参元素在当前元素集合中的index值 index:function(elem){ // 没有参数传入,first获取当前元素的首项,判断它在父节点中的序号值 if ( !elem ){ return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; } // 传参为elem,返回当前元素在$(elem)中的序号值,当前元素和$(elem)平辈 if ( typeof elem==="string" ){ return indexOf.call(jQuery(elem),this[0]); } // 若传入dom元素或jquery对象,判断它们在当前元素中的index序号 return indexOf.call(this, elem.jquery ? elem[0] : elem); }, // context下找到的selector元素添加到当前元素集合中返回 add:function(selector,context){ return this.pushStack( jQuery.uniqueSort( jQuery.merge(this.get(),jQuery(selector,context)) ) ); }, // 与end不同的是,addBack不只回到先前操作的元素集合,还包含滤除不匹配selector的元素 addBack:function(selector){ return this.add( selector==null ? this.prevObject : this.prevObject.filter(selector) ); } } ); function sibling( cur, dir ) { while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} return cur; } jQuery.each({ // 父节点 parent:function(elem){ var parent=elem.parentNode; return parent && parent.nodeType!==11 ? parent : null; }, // 祖先节点 parents:function(elem){ return dir(elem,"parentNode"); }, // 祖先节点,获取直到until级为止,until为选择器 parentsUntil:function(elem,i,until){ return dir(elem,"parentNode",until); }, // 后一个节点 next:function(elem){ return sibling(elem,"nextSibling"); }, // 前一个节点 prev:function(elem){ return sibling(elem,"previousSibling"); }, // 后续兄弟节点 nextAll:function(elem){ return dir(elem,"nextSibling"); }, // 此前的兄弟节点 prevAll:function(elem){ return dir(elem,"previousSibling"); }, // 后续兄弟节点,到until为止 nextUntil:function(elem,i,until){ return dir(elem,"nextSibling",until); }, // 之前的兄弟节点,到until为止 prevUntil:function(elem,i,until){ return dir(elem,"previousSibling",until); }, // 兄弟节点 siblings:function(elem){ return siblings((elem.parentNode || {}).firstChild,elem); }, // 直接子节点,须是元素节点 children:function(elem){ return siblings(elem.firstChild); }, // 子节点,不一定是元素节点 contents:function(elem){ return elem.contentDocument || jQuery.merge([],elem.childNodes); } },function(name,fn){ jQuery.fn[name]=function(until,selector){ // $ele.prev方法: 通过sibling函数使用原生语句获取当前元素之前的节点 // $ele.siblings方法:通过siblings函数使用原生语句查找当前元素父节点下 // 首个子节点的nextSibling节点,即当前元素的兄弟节点 // $ele.siblings方法 var matched=jQuery.map(this,fn,until); // 方法名中不带until,jQuery.fn[name]只需要单参数selector if ( name.slice(-5)!=="Until" ){ selector=until; } // 过滤 if ( selector && typeof selector==="string" ){ matched = jQuery.filter(selector,matched); } if ( this.length>1 ){ if ( !guaranteedUnique[name] ){ jQuery.uniqueSort(matched); } if ( rparentsprev.test(name) ){ matched.reverse(); } } return this.pushStack(matched); }; } ); return jQuery; });
findFilter.js
define([ "../core", "../var/indexOf", "./var/rneedsContext", "../selector" ],function(jQuery,indexOf,rneedsContext){ var risSimple=/^.[^:#\[\.,]*$/; function winnow(elements,qualifier,not){ // qualifier为函数,$.grep方法执行函数过滤 if ( jQuery.isFunction(qualifier) ){ return jQuery.grep(elements,function(elem,i){ return !!qualifier.call(elem,i,elem)!==not; }); } // qualifier为节点,比较过滤 if ( qualifier.nodeType ){ return jQuery.grep(elements,function(elem){ return (elem===qualifier)!==not; }); } // qualifier为选择器,使用jQuery.filter找到元素内部符合qualifier的元素,再调用$.grep过滤 if ( typeof qualifier==="string" ){ if ( risSimple.test(qualifier) ){ return jQuery.filter(qualifier,elements,not); } qualifier=jQuery.filter(qualifier,elements); } return jQuery.grep(elements,function(elem){ return ( indexOf.call(qualifier,elem)>-1 )!==not && elem.nodeType===1; }); } // 过滤 jQuery.filter=function(expr,elems,not){ var elem=elems[0]; if ( not ){ expr=":not("+expr+")"; } return elems.length===1 && elem.nodeType===1 ? jQuery.find.matchesSelector(elem,expr) ? [elem] : [] : jQuery.find.matches(expr,jQuery.grep(elems,function(elem){ return elem.nodeType===1; })); }; jQuery.fn.extend({ // 当前元素中查询,不是选择器时,使用$.contains过滤;不然当前元素作为find方法的context find:function(selector){ var i, ret, len=this.length, self=this; if ( typeof selector!=="string" ) { return this.pushStack(jQuery(selector).filter(function(){ for ( i=0; i<len; i++ ){ if ( jQuery.contains(self[i],this) ){ return true; } } })); } ret=this.pushStack([]); for ( i=0; i<len; i++ ){ jQuery.find(selector,self[i],ret); } return len>1 ? jQuery.uniqueSort(ret) : ret; }, // 过滤 filter:function(selector){ return this.pushStack(winnow(this,selector || [],false)); }, not:function(selector){ return this.pushStack(winnow(this,selector || [],true)); }, // 过滤找出当前元素中selector节点,以它的长度作为返回值 is:function(selector){ return !!winnow( this, typeof selector==="string" && rneedsContext.test(selector) ? jQuery(selector) : selector || [], false ).length; } }); });
相关推荐
瓜牛呱呱 2020-11-12
柳木木的IT 2020-11-04
yifouhu 2020-11-02
lei0 2020-11-02
源码zanqunet 2020-10-28
源码zanqunet 2020-10-26
一叶梧桐 2020-10-14
码代码的陈同学 2020-10-14
lukezhong 2020-10-14
lzzyok 2020-10-10
anchongnanzi 2020-09-21
clh0 2020-09-18
changcongying 2020-09-17
星辰大海的路上 2020-09-13
abfdada 2020-08-26
mzy000 2020-08-24
shenlanse 2020-08-18
zhujiangtaotaise 2020-08-18
xiemanR 2020-08-17