jQuery13代码深度分析文档格式.docx
《jQuery13代码深度分析文档格式.docx》由会员分享,可在线阅读,更多相关《jQuery13代码深度分析文档格式.docx(21页珍藏版)》请在冰豆网上搜索。
![jQuery13代码深度分析文档格式.docx](https://file1.bdocx.com/fileroot1/2022-11/21/79145afd-bb3a-4b75-a3f0-32b12c8ae69a/79145afd-bb3a-4b75-a3f0-32b12c8ae69a1.gif)
\([^()]+\)|[^()]+)这段是验证:
last或者是:
(xxx)这样的选择器
varSizzle=function(selector,context,results,seed){
//确保代码不出错,上下文存在
results=results||[];
context=context||document;
//确保上下文是dom对象
if(context.nodeType!
==1&
&
context.nodeType!
==9)
return[];
//确保选择器是String
if(!
selector||typeofselector!
=="
string"
){
returnresults;
}
varparts=[],m,set,checkSet,check,mode,extra,prune=true;
//Resetthepositionofthechunkerregexp(startfromhead)
//重置正则得匹配位置
chunker.lastIndex=0;
while((m=chunker.exec(selector))!
==null){
parts.push(m[1]);
if(m[2]){
extra=RegExp.rightContext;
break;
//Expr和Sizzle.selector指向同一个对象,这个选择器和以前的不一样,是在没有用ifelse进行判断,而是用正则进行处理,具体的代码在定义Expr中。
POS:
/:
(nth|eq|gt|lt|first|last|even|odd)(?
\((\d*)\))?
(?
=[^-]|$)/,下边的代码就是判断还有没有这样的特殊函数。
if(parts.length>
1&
Expr.match.POS.exec(selector)){
//relative是函数对象,封装了+>
~函数,意思就是typeofExpr.relative[parts[0]]==Function
if(parts.length===2&
Expr.relative[parts[0]]){
varlater="
"
match;
//Positionselectorsmustbedoneafterthefilter
//如果匹配到>
+~,处理完之后(过滤上下文),选择器中的该符号去掉,再分析选择器
while((match=Expr.match.POS.exec(selector))){
later+=match[0];
selector=selector.replace(Expr.match.POS,"
);
set=Sizzle.filter(later,Sizzle(/\s$/.test(selector)?
selector+"
*"
:
selector,context));
}else{
set=Expr.relative[parts[0]]?
[context]:
Sizzle(parts.shift(),context);
while(parts.length){
vartmpSet=[];
selector=parts.shift();
if(Expr.relative[selector])
selector+=parts.shift();
for(vari=0,l=set.length;
i<
l;
i++){
Sizzle(selector,set[i],tmpSet);
set=tmpSet;
varret=seed?
{expr:
parts.pop(),set:
makeArray(seed)}:
Sizzle.find(parts.pop(),parts.length===1&
context.parentNode?
context.parentNode:
context);
set=Sizzle.filter(ret.expr,ret.set);
0){
checkSet=makeArray(set);
prune=false;
varcur=parts.pop(),pop=cur;
Expr.relative[cur]){
cur="
;
pop=parts.pop();
if(pop==null){
pop=context;
Expr.relative[cur](checkSet,pop,isXML(context));
checkSet){
checkSet=set;
throw"
Syntaxerror,unrecognizedexpression:
"
+(cur||selector);
if(toString.call(checkSet)==="
[objectArray]"
prune){
results.push.apply(results,checkSet);
}elseif(context.nodeType===1){
for(vari=0;
checkSet[i]!
=null;
if(checkSet[i]&
(checkSet[i]===true||checkSet[i].nodeType===1&
contains(context,checkSet[i]))){
results.push(set[i]);
checkSet[i].nodeType===1){
makeArray(checkSet,results);
if(extra){
Sizzle(extra,context,results,seed);
};
jQuery1.3代码深度分析(Expr)
//Expr是选择器的核心,有很多有创意的写法,值得学习
varExpr=Sizzle.selectors={
//匹配优先级先是ID再是name最后才是tag
order:
["
ID"
"
NAME"
TAG"
],
//选择器的正则表达式
match:
{
ID:
/#((?
[\w\u00c0-\uFFFF_-]|\\.)+)/,
CLASS:
/\.((?
NAME:
/\[name=['
]*((?
[\w\u00c0-\uFFFF_-]|\\.)+)['
]*\]/,
ATTR:
/\[\s*((?
[\w\u00c0-\uFFFF_-]|\\.)+)\s*(?
(\S?
=)\s*(['
]*)(.*?
)\3|)\s*\]/,
TAG:
/^((?
[\w\u00c0-\uFFFF\*_-]|\\.)+)/,
CHILD:
(only|nth|last|first)-child(?
\((even|odd|[\dn+-]*)\))?
/,
POS:
=[^-]|$)/,
PSEUDO:
[\w\u00c0-\uFFFF_-]|\\.)+)(?
\((['
]*)((?
\([^\)]+\)|[^\2\(\)]*)+)\2\))?
/
},
//jQuery属性和HTML属性对应表
attrMap:
class"
className"
for"
htmlFor"
//jQuery句柄和DOM对象方法对应表
attrHandle:
href:
function(elem){
returnelem.getAttribute("
href"
);
//层级选择
relative:
//匹配所有紧接在prev元素后的next元素
+"
function(checkSet,part){
for(vari=0,l=checkSet.length;
varelem=checkSet[i];
if(elem){
//返回已选元素的上一个同属节点(同级节点中的上一个)
varcur=elem.previousSibling;
//这段是处理返回肯定同级dom对象
while(cur&
cur.nodeType!
==1){
cur=cur.previousSibling;
checkSet[i]=typeofpart==="
?
cur||false:
cur===part;
if(typeofpart==="
//在checkSet中以后的元素中过滤选择器part
Sizzle.filter(part,checkSet,true);
//在给定的父元素下匹配所有的子元素
>
function(checkSet,part,isXML){
//part是选择器
&
!
/\W/.test(part)){
part=isXML?
part:
part.toUpperCase();
varparent=elem.parentNode;
checkSet[i]=parent.nodeName===part?
parent:
false;
elem.parentNode:
elem.parentNode===part;
//在给定的祖先元素下匹配所有的后代元素
vardoneName="
done"
+(done++),checkFn=dirCheck;
part.match(/\W/)){
varnodeCheck=part=isXML?
checkFn=dirNodeCheck;
checkFn("
parentNode"
part,doneName,checkSet,nodeCheck,isXML);
//匹配prev元素之后的所有siblings元素
~"
previousSibling"
//find对象的方法都是很简单了,前边也是做过解释
find:
function(match,context){
if(context.getElementById){
varm=context.getElementById(match[1]);
returnm?
[m]:
[];
returncontext.getElementsByName?
context.getElementsByName(match[1]):
null;
returncontext.getElementsByTagName(match[1]);
//过滤之前处理选择器
preFilter:
//css查找
function(match,curLoop,inplace,result,not){
match="
+match[1].replace(/\\/g,"
)+"
curLoop[i];
//异域处理
if(not^("
+curLoop[i].className+"
).indexOf(match)>
=0){
inplace)
result.push(curLoop[i]);
}elseif(inplace){
curLoop[i]=false;
returnfalse;
//ID查找,这个就很简单了
function(match){
returnmatch[1].replace(/\\/g,"
//TAG查找,返回标签的大写字符
function(match,curLoop){
curLoop[i];
i++){}
returnisXML(curLoop[i])?
match[1]:
match[1].toUpperCase();
//奇偶或者是位置处理
if(match[1]=="
nth"
//解析位置比如eventodd52n等等
//parseequationslike'
even'
'
odd'
5'
2n'
3n+2'
4n-1'
-n+6'
vartest=/(-?
)(\d*)n((?
\+|-)?
\d*)/.exec(
match[2]=="
even"
2n"
||match[2]=="
odd"
2n+1"
||