作者:nuysoft/高云 QQ:47214707 Email:nuysoft@gmail.com
声明:本文为原创文章,如需转载,请注明来源并保留原文链接。
1. DOM遍历有3个核心函数:
jQuery.dir( elem, dir, until ) 从一个元素出发,迭代检索某个方向上的所有元素并记录,直到与遇到document对象或遇到until匹配的元素 jQuery.nth( cur, result, dir, elem ) 从一个元素出发,迭代检索某个方向上的第N个元素 jQuery.sibling( n, elem ) 元素n的所有后续兄弟元素,包含n,不包含elem
jQuery对象上的DOM遍历方法(大部分)被转换对这3个核心函数的调用,而这3个核心函数最后又都转换为对原生API的操作,看看他们之间的关系:
核心函数 jQuery对象方法 含义 用到的原生API jQuery.dir parents 祖先元素 parentNode parentsUntil 祖先元素,但是不包括until parentNode nextAll
所有的兄弟元素
nextSibling
prevAll
所有的兄长元素
previousSibling
nextUntil
所有的兄弟元素,但是不包括until
nextSibling
prevUntil
所有的兄长元素,但是不包括until
previousSibling
jQuery.nth
next
下一个兄弟元素
nextSibling
prev
上一个兄长元素
previousSibling
jQuery.sibling
siblings
所有兄长、兄弟元素,不包括当前元素
elem.parentNode.firstChild
children
所有的子节点
elem.firstChild
2. jQuery.dir( elem, dir, until )
/**
* 从一个元素出发,迭代检索某个方向上的所有元素并记录,直到与遇到document对象或遇到until匹配的元素
* 迭代条件(简化):cur.nodeType !== 9 && !jQuery( cur ).is( until )
* elem 起始元素
* dir 迭代方向,可选值:parentNode nextSibling previousSibling
* until 选择器表达式,如果遇到until匹配的元素,迭代终止
*/
dir: function( elem, dir, until ) { // 这个函数很精髓,短短几行代码,支持遍历祖先、所有兄长、所有兄弟!
var matched = [], // 匹配结果
cur = elem[ dir ]; // 第一次访问,尝试在方向dir上取一次,为循环提供第一次判断(变量cur多余,只用elem就可满足)
// 不包含自身
/**
* 迭代访问,直到遇到document对象或遇到until匹配的元素
* cur.nodeType !== 9 当前DOM节点cur不是document对象
* !jQuery( cur ).is( until ) 当前DOM节点cur不匹配表达式until
*
* until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )
* 这个布尔表达式也有点意思,执行最后的jQuery.is的隐含条件是:until !== undefined && cur.nodeType === 1
* 复合的布尔表达式和三元表达式,能减少代码行数、稍微提升性能,但是代码晦涩,不易阅读和维护。
* 也许看不懂也是jQuery风靡的原因之一
*/
while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
if ( cur.nodeType === 1 ) { // 如果是Element,则放入匹配结果数组
matched.push( cur );
}
cur = cur[dir]; // 将方向dir上的下一个节点,设置为当前节点,继续访问
}
return matched;
}
3. jQuery.nth( cur, result, dir, elem )
/**
* 从一个元素出发,迭代检索某个方向上的第N个元素
* cur 起始元素
* result 第几个,1表示当前元素,2表示下一个,以此类推(搞不明白为什么从1开始?)
* dir 迭代方向
* elem 多余
*/
nth: function( cur, result, dir, elem ) {
result = result || 1; // 第几个?默认从1开始?嗯,这里从1开始计数,1表示当前元素,2表示下一个,以此类推
var num = 0; // 操蛋的初始值,初始为1更好理解
// 下边的for循环看的蛋疼!
// dir先在方向dir上取一次再循环,nth先循环一次然后再取
// dir不包含自身,nth包含自身
for ( ; cur; cur = cur[dir] ) { // 某个方向
if ( cur.nodeType === 1 && ++num === result ) { // 先加后取值,num等于1时检查的是当前元素
break;
}
}
// 如果result为0或1,则取当前元素
// 如果result小于0,则返回undefined
return cur;
}
4. jQuery.nth( cur, result, dir, elem )
/**
* 元素n的所有后续兄弟元素,包含n,不包含elem
* n 起始元素(包含在返回结果中)
* elem 排除元素
*/
sibling: function( n, elem ) {
var r = [];
for ( ; n; n = n.nextSibling ) { // 先判断再取,结果中包含n
// nodeType === 1,只能是Element,过滤了其他的Text、Attr、Comment等元素
if ( n.nodeType === 1 && n !== elem ) {
r.push( n );
}
}
return r;
}
作者:nuysoft/高云 QQ:47214707 Email:nuysoft@gmail.com
声明:本文为原创文章,如需转载,请注明来源并保留原文链接。
1. DOM遍历有3个核心函数:
jQuery.dir( elem, dir, until ) | 从一个元素出发,迭代检索某个方向上的所有元素并记录,直到与遇到document对象或遇到until匹配的元素 |
jQuery.nth( cur, result, dir, elem ) | 从一个元素出发,迭代检索某个方向上的第N个元素 |
jQuery.sibling( n, elem ) | 元素n的所有后续兄弟元素,包含n,不包含elem |
jQuery对象上的DOM遍历方法(大部分)被转换对这3个核心函数的调用,而这3个核心函数最后又都转换为对原生API的操作,看看他们之间的关系:
核心函数 | jQuery对象方法 | 含义 | 用到的原生API |
jQuery.dir | parents | 祖先元素 | parentNode |
parentsUntil | 祖先元素,但是不包括until | parentNode | |
nextAll | 所有的兄弟元素 | nextSibling | |
prevAll | 所有的兄长元素 | previousSibling | |
nextUntil | 所有的兄弟元素,但是不包括until | nextSibling | |
prevUntil | 所有的兄长元素,但是不包括until | previousSibling | |
jQuery.nth | next | 下一个兄弟元素 | nextSibling |
prev | 上一个兄长元素 | previousSibling | |
jQuery.sibling | siblings | 所有兄长、兄弟元素,不包括当前元素 | elem.parentNode.firstChild |
children | 所有的子节点 | elem.firstChild |
2. jQuery.dir( elem, dir, until )
/** * 从一个元素出发,迭代检索某个方向上的所有元素并记录,直到与遇到document对象或遇到until匹配的元素 * 迭代条件(简化):cur.nodeType !== 9 && !jQuery( cur ).is( until ) * elem 起始元素 * dir 迭代方向,可选值:parentNode nextSibling previousSibling * until 选择器表达式,如果遇到until匹配的元素,迭代终止 */ dir: function( elem, dir, until ) { // 这个函数很精髓,短短几行代码,支持遍历祖先、所有兄长、所有兄弟! var matched = [], // 匹配结果 cur = elem[ dir ]; // 第一次访问,尝试在方向dir上取一次,为循环提供第一次判断(变量cur多余,只用elem就可满足) // 不包含自身 /** * 迭代访问,直到遇到document对象或遇到until匹配的元素 * cur.nodeType !== 9 当前DOM节点cur不是document对象 * !jQuery( cur ).is( until ) 当前DOM节点cur不匹配表达式until * * until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until ) * 这个布尔表达式也有点意思,执行最后的jQuery.is的隐含条件是:until !== undefined && cur.nodeType === 1 * 复合的布尔表达式和三元表达式,能减少代码行数、稍微提升性能,但是代码晦涩,不易阅读和维护。 * 也许看不懂也是jQuery风靡的原因之一 */ while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { if ( cur.nodeType === 1 ) { // 如果是Element,则放入匹配结果数组 matched.push( cur ); } cur = cur[dir]; // 将方向dir上的下一个节点,设置为当前节点,继续访问 } return matched; } |
3. jQuery.nth( cur, result, dir, elem )
/** * 从一个元素出发,迭代检索某个方向上的第N个元素 * cur 起始元素 * result 第几个,1表示当前元素,2表示下一个,以此类推(搞不明白为什么从1开始?) * dir 迭代方向 * elem 多余 */ nth: function( cur, result, dir, elem ) { result = result || 1; // 第几个?默认从1开始?嗯,这里从1开始计数,1表示当前元素,2表示下一个,以此类推 var num = 0; // 操蛋的初始值,初始为1更好理解 // 下边的for循环看的蛋疼! // dir先在方向dir上取一次再循环,nth先循环一次然后再取 // dir不包含自身,nth包含自身 for ( ; cur; cur = cur[dir] ) { // 某个方向 if ( cur.nodeType === 1 && ++num === result ) { // 先加后取值,num等于1时检查的是当前元素 break; } } // 如果result为0或1,则取当前元素 // 如果result小于0,则返回undefined return cur; } |
4. jQuery.nth( cur, result, dir, elem )
/** * 元素n的所有后续兄弟元素,包含n,不包含elem * n 起始元素(包含在返回结果中) * elem 排除元素 */ sibling: function( n, elem ) { var r = []; for ( ; n; n = n.nextSibling ) { // 先判断再取,结果中包含n // nodeType === 1,只能是Element,过滤了其他的Text、Attr、Comment等元素 if ( n.nodeType === 1 && n !== elem ) { r.push( n ); } } return r; } |