function Sizzle( selector, context, results, seed ) {
var match, elem, m, nodeType,
// QSA vars
i, groups, old, nid, newContext, newSelector;
//注意這個document只是個普通的變量
//setDocument()方法根據當前運行代碼的環境,設置當前的document
//傳入的context的doucument和當前document不一樣時
//調用setDocument()
//用於在 frame 中的情況
//context爲document時,context.ownerDocument爲null
if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
//設置正確的document
setDocument( context );
}
//上下文爲傳入context或調用setDocument()後的document
context = context || document;
//查詢結果集
results = results || [];
//如果沒傳入選擇器表達式或者傳入的選擇器表達器類型不是string
if ( !selector || typeof selector !== "string" ) {
//返回
return results;
}
//如果上下文不是Element或Document
//返回空結果集
if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
return [];
}
//文檔是HTML並且沒有傳入候選集seed
if ( documentIsHTML && !seed ) {
// Shortcuts
// 快速匹配最常用的單一id tag class
//rquickExpr 捕獲組1:id 捕獲組2:tag 捕獲組3:class
if ( (match = rquickExpr.exec( selector )) ) {
// Speed-up: Sizzle("#ID")
//id 分支
if ( (m = match[1]) ) {
//context是document
if ( nodeType === 9 ) {
elem = context.getElementById( m );
// Check parentNode to catch when Blackberry 4.6 returns
// nodes that are no longer in the document (jQuery #6963)
if ( elem && elem.parentNode ) {
// Handle the case where IE, Opera, and Webkit return items
// by name instead of ID
//看上面註釋!
if ( elem.id === m ) {
results.push( elem );
return results;
}
} else {
return results;
}
} else {
// Context is not a document
//得到上下文所屬document,然後調用document.getElementById,並判斷得到的elem是否屬於contains並且看看elem的id屬性是否等於m
if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&
contains( context, elem ) && elem.id === m ) {
results.push( elem );
return results;
}
}
// Speed-up: Sizzle("TAG")
// tag分支
} else if ( match[2] ) {
push.apply( results, context.getElementsByTagName( selector ) );
return results;
// Speed-up: Sizzle(".CLASS")
// class分支
} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {
push.apply( results, context.getElementsByClassName( m ) );
return results;
}
}
// QSA path
// 支持querySelectorAll,rbuggyQSA怪癖檢查
if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
nid = old = expando;
newContext = context;
//newSelector的值爲false或selector
//如果nodeType !== 9 返回false,其他返回selector
newSelector = nodeType === 9 && selector;
// qSA works strangely on Element-rooted queries
// We can work around this by specifying an extra ID on the root
// and working up from there (Thanks to Andrew Dupont for the technique)
// IE 8 doesn't work on object elements
//如果調通querySelectorAll的是Element會出現一些怪異的問題
//所以在原selector的基礎上方添加一個id的屬性選擇器
//例如媛selector:div a,修正後爲[id='xx'] div a
if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) {
groups = tokenize( selector );
//如果Element元素有id,則使用原來id
if ( (old = context.getAttribute("id")) ) {
//rescape = /'|\\/g
nid = old.replace( rescape, "\\$&" );
//沒有id設置一個臨時id,此id是expando屬性
} else {
context.setAttribute( "id", nid );
}
nid = "[id='" + nid + "'] ";
i = groups.length;
while ( i-- ) {
groups[i] = nid + toSelector( groups[i] );
}
newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;
newSelector = groups.join(",");
}
//修正newSelector,調用querySelectorAll
if ( newSelector ) {
try {
push.apply( results,
newContext.querySelectorAll( newSelector )
);
return results;
} catch(qsaError) {
} finally {
//如果用的時臨時id
//刪除
if ( !old ) {
context.removeAttribute("id");
}
}
}
}
}
// All others
//原生方法不可用時,調用
return select( selector.replace( rtrim, "$1" ), context, results, seed );
}
JQuery_2.1.0_日記 5.5 Sizzle選擇器(三)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.