`

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;
	}
});

});

 

 

0
2
分享到:
评论

相关推荐

    《锋利的JQuery》实例源码

    - `traversing.js`: 可能包含DOM遍历的方法,如`parent()`, `children()`, `siblings()`等,帮助理解元素之间的关系操作。 2. **DOM操作** - `manipulation.js`: 文件中可能包括DOM元素的创建、插入、删除等操作...

    jquery源码好不容易找到的与大家分享

    1. **模块化设计**:jQuery源码采用模块化设计,分为多个部分,如`selector.js`(选择器引擎)、`core.js`(核心功能)、`traversing.js`(遍历DOM)等,这有利于代码的组织和维护。 2. **函数封装**:jQuery将所有...

    jquery-1.11源码

    源码中的`init.js`初始化了这个对象,使其成为一个可扩展的集合。 10. **性能优化** jQuery 1.11在性能上进行了诸多优化,例如,利用`documentfragment`批量处理DOM操作,减少DOM操作次数,以及使用`try...catch`...

    zeptojs 常用方法使用及使用源码

    zepto.js 是一个轻量级的JavaScript库,专为移动Web开发设计,它提供了与jQuery相似的API,但体积更小,更适合移动端的性能优化。本文将深入探讨zepto.js的常用方法及其源码解析。 一、zepto.js简介 zepto.js 的...

    jqueryapi.rar_源码

    《jQuery API 源码详解与应用实践》 在网页开发中,jQuery 是一个不可或缺的JavaScript库,它极大地简化了JavaScript的DOM操作、事件处理、动画制作和Ajax交互。本资料主要围绕“jqueryapi.rar”这个压缩包中的...

    《锋利的jQuery》实例源码.rar

    《锋利的jQuery》是一本深受开发者喜爱的jQuery教程书籍,其实例源码rar压缩包包含了大量的实践案例,旨在帮助读者深入理解和掌握jQuery这一强大的JavaScript库。jQuery以其简洁的API和丰富的功能,使得网页交互变得...

    jquery-1.9.1.zip

    `jquery-1.9.1.js`是未压缩的源码文件,对于开发者来说非常有用,因为它提供了可读性强的代码,方便在开发过程中进行调试和学习。这个文件包含了jQuery的核心功能,如选择器(Selectors)、遍历(Traversing)、DOM...

    jQuery源码分析系列.pdf

    此外,文档还提到了选择器Sizzle、DOM遍历Traversing、DOM操作Manipulation等高级特性,这些都是在深入使用jQuery时会频繁用到的工具和方法。Sizzle选择器引擎的选择器执行机制、DOM遍历和操作的内部实现,都展示了...

    Jquery几个实例源码

    9. **遍历(Traversing)**:jQuery提供了遍历DOM结构的方法,如`.parent()`, `.children()`, `.siblings()`, `.next()`, `.prev()`等,便于操作相关元素。 10. **回调函数(Callback Functions)**:在动画或异步...

    jquery源码

    1. **家族遍历(Traversing)**:`parent()`, `children()`, `siblings()`, `next()`, `prev()`等方法帮助我们遍历元素的关系,更好地控制DOM结构。 2. **过滤与查找(Filtering & Searching)**:通过`filter...

    jQuery实现的电子商务网站首页幻灯片效果源码.zip

    这个"jQuery实现的电子商务网站首页幻灯片效果源码.zip"压缩包包含的是一套使用jQuery编写的电子商务网站首页面幻灯片展示代码。这种效果通常用于在网站的首页上循环展示产品、促销或特色内容,以吸引用户的注意力并...

    锋利的JQuery第二版的源码

    《锋利的jQuery》是jQuery学习的经典著作,其第二版更是深入浅出地解析了这一广泛使用的JavaScript库。...同时,源码分析还能帮助我们了解如何设计和组织一个大型JavaScript库,这对于提升自身开发能力具有重要意义。

    带锋利的JQuery第二版的源码

    通过深入学习《带锋利的jQuery第二版》的源码,开发者不仅可以了解jQuery的工作原理,还能学习到优秀的JavaScript编程实践和模式,提升自己的JavaScript技能。此外,源码阅读也能帮助开发者在遇到性能问题时,更好地...

    jQuery实现个性动画彩色Tabs选项卡特效源码.zip

    在这个“jQuery实现个性动画彩色Tabs选项卡特效源码.zip”压缩包中,包含了一个使用jQuery编写的彩色动画选项卡(Tabs)特效的源代码。这种效果可以提升用户体验,使得网页内容组织更有序,用户可以通过点击不同的...

    jquery源码和API

    jQuery的源码组织结构清晰,分为核心(core)、选择器(selector)、DOM操作(manipulation)、事件(events)、遍历(traversing)、效果(effects)等多个模块。源码中大量使用了闭包和原型链,以提高效率和封装性...

    LearningJQuery源码

    jQuery的源码分为多个模块,如选择器(Selectors)、遍历(Traversing)、事件(Events)、效果(Effects)、Ajax(Ajax)等,每个模块都有其特定的功能和优化策略。通过分析这个文件,我们可以了解到jQuery是如何...

    《锋利的jQuery》实例源码

    同时,这些源码也展示了良好的编程实践,如代码组织、性能优化等,对于提升JavaScript开发技能大有裨益。在阅读和分析源码的过程中,不断实践和调试,将加速学习过程,使开发者更加熟练地驾驭jQuery这个强大的工具。

    《锋利的jQuery》+源码.

    jQuery是一个广泛使用的JavaScript库,它的出现极大地简化了JavaScript的DOM操作、事件处理、动画效果和Ajax交互。jQuery的核心特性包括选择器(Selectors)、遍历(Traversing)、属性操作(Attributes)以及事件...

    《锋利的Jquery》高清扫描版--内附实例源码

    3. Traversing:jQuery提供了遍历DOM树的方法,如`$(selector).children()`, `$(selector).parent()`, `$(selector).siblings()`等,便于在DOM结构中导航。 三、jQuery AJAX 1. AJAX请求:`$.ajax()`是jQuery的...

    jQuery实现递归无限极树状菜单特效源码.zip

    jQuery,作为广泛使用的JavaScript库,提供了丰富的功能和简便的API,使得实现动态、交互性强的树状菜单变得轻而易举。本文将深入探讨如何利用jQuery来实现递归无限级的树状菜单特效,以期为开发者提供实用的参考。 ...

Global site tag (gtag.js) - Google Analytics