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;
}
});
}); 相关推荐
瓜牛呱呱 2020-11-12
柳木木的IT 2020-11-04
yifouhu 2020-11-02
lei0 2020-11-02
源码zanqunet 2020-10-26
码代码的陈同学 2020-10-14
lukezhong 2020-10-14
clh0 2020-09-18
changcongying 2020-09-17
星辰大海的路上 2020-09-13
abfdada 2020-08-26
mzy000 2020-08-24
shenlanse 2020-08-18
zhujiangtaotaise 2020-08-18
xiemanR 2020-08-17