JQuery日记 6.3 JQuery遍历模块

jQuery.extend({
	// 返回elem延DOM树某个方向访问的所有节点,直到遇到until条件
	dir: 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;
	},

	//返回n的兄弟节点(把n,elem设为相同元素时,不返回本身)
	sibling: function( n, elem ) {
		var matched = [];

		for ( ; n; n = n.nextSibling ) {
			if ( n.nodeType === 1 && n !== elem ) {
				matched.push( n );
			}
		}

		return matched;
	}
});

jQuery.fn.extend({
	has: function( target ) {
		// 以当前jquery对象为上下文查找target
		var targets = jQuery( target, this ),
			l = targets.length;
		// 过滤掉当前JQuery不包含target后代的元素
		return this.filter(function() {
			var i = 0;
			for ( ; i < l; i++ ) {
				if ( jQuery.contains( this, targets[i] ) ) {
					return true;
				}
			}
		});
	},

	// 返回包含符合selector元素的最近的JQuery对象
	// 返回的可能是其包含自己或其父类的JQuery对象,其长度为0或1
	closest: function( selectors, context ) {
		var cur,
			i = 0,
			l = this.length,
			matched = [],
			pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ?
				jQuery( selectors, context || this.context ) :
				0;

		for ( ; i < l; i++ ) {
			// 从本身开始,然后沿父类继续
			for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {
				// Always skip document fragments
				// 如果pos是以$(selectors,context)查找出的JQuery对象
				if ( cur.nodeType < 11 && (pos ?
					// pos中是否可查找到cur元素
					pos.index(cur) > -1 :
					// 否则查看cur是否满足selectors选择表达式
					// Don't pass non-elements to Sizzle
					cur.nodeType === 1 &&
						jQuery.find.matchesSelector(cur, selectors)) ) {

					matched.push( cur );
					break;
				}
			}
		}

		return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );
	},

	// Determine the position of an element within
	// the matched set of elements
	index: function( elem ) {

		// No argument, return index in parent
		// 没有传入参数返回在同辈元素中的位置
		if ( !elem ) {
			return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
		}

		// index in selector
		// 参数是选择器
		if ( typeof elem === "string" ) {
			// 返回本JQuery对象第一个元素在匹配所有此选择器的JQuery对象的位置
			return indexOf.call( jQuery( elem ), this[ 0 ] );
		}

		// Locate the position of the desired element
		// 返回参数元素在此JQuery对象的位置
		return indexOf.call( this,

			// If it receives a jQuery object, the first element is used
			elem.jquery ? elem[ 0 ] : elem
		);
	},

	// 在当前JQuery对象中添加额外元素
	add: function( selector, context ) {
		return this.pushStack(
			jQuery.unique(
				jQuery.merge( this.get(), jQuery( selector, context ) )
			)
		);
	},

	// 将调用链上前一个JQuery中的元素添加到当前JQuery对象中
	// selector参数用于过滤前一个JQuery对象
	addBack: function( selector ) {
		return this.add( selector == null ?
			this.prevObject : this.prevObject.filter(selector)
		);
	}
});

// 沿DOM树某个方向获取下一个DOM元素
function sibling( cur, dir ) {
	// 一直遇到DOM元素再停下
	while ( (cur = cur[dir]) && cur.nodeType !== 1 ) {}
	return cur;
}
// 绑定快捷遍历JQuery对象方法
jQuery.each({
	parent: function( elem ) {
		var parent = elem.parentNode;
		return parent && parent.nodeType !== 11 ? parent : null;
	},
	parents: function( elem ) {
		return jQuery.dir( elem, "parentNode" );
	},
	parentsUntil: function( elem, i, until ) {
		return jQuery.dir( elem, "parentNode", until );
	},
	next: function( elem ) {
		return sibling( elem, "nextSibling" );
	},
	prev: function( elem ) {
		return sibling( elem, "previousSibling" );
	},
	nextAll: function( elem ) {
		return jQuery.dir( elem, "nextSibling" );
	},
	prevAll: function( elem ) {
		return jQuery.dir( elem, "previousSibling" );
	},
	nextUntil: function( elem, i, until ) {
		return jQuery.dir( elem, "nextSibling", until );
	},
	prevUntil: function( elem, i, until ) {
		return jQuery.dir( elem, "previousSibling", until );
	},
	siblings: function( elem ) {
		return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );
	},
	children: function( elem ) {
		return jQuery.sibling( elem.firstChild );
	},
	// frame里的所有子元素
	contents: function( elem ) {
		return elem.contentDocument || jQuery.merge( [], elem.childNodes );
	}
}, function( name, fn ) {
	// 在JQuery的原型对象上绑定快捷遍历函数
	jQuery.fn[ name ] = function( until, selector ) {
		// this指调用此方法的JQuery对象
		// 根据不同遍历的fn,将this中的元素映射成其遍历后的元素
		var matched = jQuery.map( this, fn, until );

		// 如果方法不是没有终止条件(Until)
		// 修正selector为第一个参数
		if ( name.slice( -5 ) !== "Until" ) {
			selector = until;
		}

		if ( selector && typeof selector === "string" ) {
			// 过滤matched中不符合selecotr的元素
			matched = jQuery.filter( selector, matched );
		}

		// this中如果有多个元素,那么遍历后的matched可能存在重复
		if ( this.length > 1 ) {
			// Remove duplicates
			if ( !guaranteedUnique[ name ] ) {
				jQuery.unique( matched );
			}

			// Reverse order for parents* and prev-derivatives
			// parent或pare的遍历matched应该反转,使matched顺序更符合逻辑
			if ( rparentsprev.test( name ) ) {
				matched.reverse();
			}
		}
		// 返回以matched为元素的新的JQuery对象
		return this.pushStack( matched );
	};
});

JQuery日记 6.3 JQuery遍历模块,布布扣,bubuko.com

时间: 2024-08-06 03:47:12

JQuery日记 6.3 JQuery遍历模块的相关文章

JQuery日记 5.31 JQuery对象的生成

JQuery对象的生成 1 selector为任何可转换false的空值 返回空JQuery对象 2 selector为字符串 2.1 selector为html字符串或有id属性的标签 2.2.1 selector为html字符时 转换html字符为DOM元素并放入当前JQuery的数组 当context参数为js对象时,迭代器属性 (1)当前属性对应此JQuery对象的某个函数时,调用此JQuery对象的此函数,参数为当前属性的值. (2)其他设置HTML属性 2.2.2 selector有

jQuery 源码分析(十九) DOM遍历模块详解

jQuery的DOM遍历模块对DOM模型的原生属性parentNode.childNodes.firstChild.lastChild.previousSibling.nextSibling进行了封装和扩展,用于在DOM树中遍历父元素.子元素和兄弟元素. 可以通过jQuery的实例来访问,方法如下: parent()             ;获取匹配元素的父元素 parents(selector)         ;获取匹配元素的所有祖先元素                        ;s

JQuery日记 5.11 Sizzle选择器(五)

//设置当前document和document对应的变量和方法 setDocument = Sizzle.setDocument = function( node ) { var hasCompare, //node为Element时返回node所属document //node为Document时返回node //node为空时返回window.document doc = node ? node.ownerDocument || node : preferredDoc, //document

JQuery日记_5.13 Sizzle选择器(六)选择器的效率

当选择表达式不符合快速匹配(id,tag,class)和原生QSA不可用或返回错误时,将调用select(selector, context, results, seed)方法,此方法迭代DOM选择.过滤元素, 在DOM树非常大的时候为了保证效率,应该保证html设计的合理,尽量使用可快速匹配(id,tag,class)的表达式,其次是QSA支持的选择器,尽量不要使用jquery扩展的selector和嵌套selector,然后是尽量不要使用位置伪类(它是从左向右查找,需要多次循环内套循环遍历)

jQuery -&gt; 基于当前元素的遍历

pcDuino3下支持mmc启动,官方的Uboot是采用SPL框架实现的,因为内部的SRAM空间达到32K,我们完全可以在这32K空间内编写一个完整可用小巧的bootloader来完成引导Linux kernel的目的. 我们首先介绍下SPL框架,可以先看下<GNU ARM汇编--(十八)u-boot-采用nand_spl方式的启动方法>和<GNU ARM汇编--(十九)u-boot-nand-spl启动过程分析>,NAND_SPL也算是SPL框架下的一种模式. 当使用Nand f

jquery 对 Json 的各种遍历

概述 JSON(javascript Object Notation) 是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,是理想的数据交换格式.同时,JSON是 JavaScript 原生格式,这意味着在 JavaScript 中处理 JSON数据不须要任何特殊的 API 或工具包. 在JSON中,有两种结构:对象和数组. 1.对象 一个对象以“{”开始,“}”结束.每个“key”后跟一“:”,“‘key/value’ 对”之间运用 “,”分隔. packJson = {"name&qu

JQuery日记_5.14 Sizzle选择器(七)

上篇说道,tokenize方法会把selector分割成一个个selector逻辑单元(如div>a是三个逻辑单元 'div','>','a')并为之片段赋予对应类型的过滤函数. for ( type in Expr.filter ) { if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || (match = preFilters[ type ]( match ))) ) { matc

JQuery日记6.5 Javascript异步模型(二)

mnesia在频繁操作数据的过程可能会报错:** WARNING ** Mnesia is overloaded: {dump_log, write_threshold},可以看出,mnesia应该是过载了.这个警告在mnesia dump操作会发生这个问题,表类型为disc_only_copies .disc_copies都可能会发生. 如何重现这个问题,例子的场景是多个进程同时在不断地mnesia:dirty_write/2 mnesia过载分析 1.抛出警告是在mnesia 增加dump

JQuery日记 2014-4.28

为方便起见将JQuery.fn.init称之为JQuery对象 JQuery原型对象方法: (1) toArray() 调用[].prototype.slice.call(jquery)将JQuery对象(类对象)转换为真正的数组 测试html <body> <div id= "div1">div1</div ><div id= "div2">div2</div > <span> span1&l