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-26  
   码代码的陈同学    2020-10-14  
   lukezhong    2020-10-14  
   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  
 