另外,还需要处理的特殊情况是: 如果当前jQuery对象所匹配的元素有多个,则使用parents /prevUntil /prevAll这三种筛选的结果需要倒序排列。需要倒序的原因:jQuery.unique使用的是Sizzle引擎中的排序函数Sizzle .uniqueSort,这个排序函数会根据文档最顶层对象到最底层的方式排列。
if ( this.length > 1 && rparentsprev.test( name ) ) {
ret = ret.reverse();
}
最后,返回包裹后的结果
return this.pushStack( ret );
上面说了主题的框架结构,下面说一下这一组筛选器匹配函数里面用到的两个函数jQuery.dir和jQuery. sibling,直接上源码
//从当前元素elem指定的dir对应的节点开始一直查找dir,并将这些节点保存在matched中,直到循环终止。注意:结果中不包含elem节点
dir: function( elem, dir, until ) {
var matched = [],
cur = elem[ dir ];
while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {
if ( cur.nodeType === 1 ) {
matched.push( cur );
}
cur = cur[dir];
}
return matched;
},
//获取节点n及其兄弟节点中非elem的节点集合r
sibling: function( n, elem ) {
var r = [];
for ( ; n; n = n.nextSibling ) {
if ( n.nodeType === 1 && n !== elem ) {
r.push( n );
}
}
return r;
}
//找到当前元素cur的下一个dir为止
function sibling( cur, dir ) {
do {
cur = cur[ dir ];
} while ( cur && cur.nodeType !== 1 );
return cur;
}
jQuery.fn.add( selector, context )和jQuery.fn. addBack( selector )
add函数是向当前匹配元素中添加符合指定表达式的元素,并以jQuery对象的形式返回。add可以接收包括:选择器(字符串)、HTML内容(字符串)、DOM元素(Element)、jQuery对象。处理比较简单,直接上源码
add: function( selector, context ) {
var set = typeof selector === "string" ?
jQuery( selector, context ) :
jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),
//把selector表达式获取的结果集拼接到当前对象上
all = jQuery.merge( this.get(), set );
//返回新的拼接结果
return this.pushStack( jQuery.unique(all) );
}
jQuery.fn.add和jQuery.fn.not相对应。jQuery.fn.not后面再说。
jQuery.fn.addBack将之前匹配的元素加入到当前匹配的元素中,并以新的jQuery对象的形式返回。
addBack: function( selector ) {
return this.add( selector == null ?
this.prevObject : this.prevObject.filter(selector)
);
}
jQuery.fn.andSelf = jQuery.fn.addBack;
jQuery.fn.not( selector )和jQuery.fn.filter( selector )
not: function( selector ) {
return this.pushStack( winnow(this, selector, false) );
}
filter: function( selector ) {
return this.pushStack( winnow(this, selector, true) );
},
not和filter都是操作本身的集合,not是过滤掉本身集合中满足过滤条件selector的项,留下其他项。而filter是留下满足过滤条件selector的项。
关键是function winnow( elements, qualifier, keep )函数。这个函数的功能是执行相同的过滤或者不过滤的功能。过滤条件qualifier有三种:函数、DOM节点、字符串。keep:true表示保留满足过滤条件的项,false表示保留不满足过滤条件的项。
winnow的源码注释如下
//执行相同的过滤或者不过滤的功能
function winnow( elements, qualifier, keep ) {
// Can't pass null or undefined to indexOf in Firefox 4
// Set to 0 to skip string check
qualifier = qualifier || 0;
//如果过滤条件是函数,则通过过滤函数过滤
if ( jQuery.isFunction( qualifier ) ) {
return jQuery.grep(elements, function( elem, i ) {
var retVal = !!qualifier.call( elem, i, elem );
return retVal === keep;
});
//如果过滤条件是DOM相关类型,通过比较节点是否相同来过滤
} else if ( qualifier.nodeType ) {
return jQuery.grep(elements, function( elem ) {
return ( elem === qualifier ) === keep;
});
//如果过滤条件是字符串
} else if ( typeof qualifier === "string" ) {
//过滤出elements中的节点元素
var filtered = jQuery.grep(elements, function( elem ) {
return elem.nodeType === 1;
});
// 其中isSimple = /^.[^:#[.,]*$/
if ( isSimple.test( qualifier ) ) {
return jQuery.filter(qualifier, filtered, !keep);
} else {
//查找filtered中满足筛选条件qualifier的节点
qualifier = jQuery.filter( qualifier, filtered );
}
}
//过滤出elements中满足过滤条件的元素
return jQuery.grep(elements, function( elem ) {
return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep;
});
}更多:js清空css样式Jquery 1.9.1源码分析系列(十二)之筛选操作
https://www.002pc.comhttps://www.002pc.com/javascript/167.html
你可能感兴趣的源码,Jquery,1.9,筛选,十二,系列
