break;
}
}
}
}
ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
return this.pushStack( ret, "closest", selectors );
},
恰逢我也想造个轮子,便去研究它一翻,发现其第一个可以是字符串,元素节点或jQuery对象,还有一个可选参数,上下文。看源码前几句,发现有个分支是判断是否是Array,估计是供内部调用的优化代码,可以无视之。于是其方法简化为:
closest: function( selectors, context ) {
var ret = [], i, l, cur = this[0];
// 如果字符串包含位置伪类或者是个元素节点,则封装为一个jQuery对象,否则为0(即false的简写,用于快速跳过分支)
var pos = POS.test( selectors ) || typeof selectors !== "string" ?
jQuery( selectors, context || this.context ) :
0;
//遍历原jQuery对象的节点
for ( i = 0, l = this.length; i < l; i++ ) {
cur = this[i];
while ( cur ) {
//如果是jQuery对象,则判定其是否包含当前节点,否则使用matchesSelector方法判定这个节点是否匹配给定的表达式selectors
if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
//是则放入选择器中
ret.push( cur );
break;
} else {
// 否则把当前节点变为其父节点
cur = cur.parentNode;
if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
break;
}
}
}
}
//如果大于1,进行唯一化操作
ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
//将节点集合重新包装成一个新jQuery对象返回
return this.pushStack( ret, "closest", selectors );
},
由于本人很反感位置伪类,认为其违反选择器的法则之一(由关系选择器隔开的各选择器分组内部,它们的位置是随意的),因此有关位置伪类的逻辑我也去掉了。
closest: function( selectors ) {
var ret = [], i, l, cur = this[0];
// 如果字符串包含位置伪类或者是个元素节点,则封装为一个jQuery对象,否则为0(即false的简写,用于快速跳过分支)
var node = selectors.nodeType ? selectors :false;
var nodes = [].slice.call(this);//将jQuery对象转换为纯数组
//遍历原jQuery对象的节点
for ( i = 0, l = this.length; i < l; i++ ) {
cur = this[i];
while ( cur ) {
//如果是jQuery对象,则判定其是否包含当前节点,否则使用matchesSelector方法判定这个节点是否匹配给定的表达式selectors
if ( obj ? nodes.indexOf(node) > -1 : jQuery.find.matchesSelector(cur, selectors) ) {
2/4 首页 上一页 1 2 3 4 下一页 尾页 |