对jQuery的Sizzle各方法做了深入分析(同时也参考了一些网上资料)后,将结果分享给大家。我将采用连载的方式,对Sizzle使用的一些方法详细解释一下,每篇文章介绍一个方法。
若需要转载,请写明出处,多谢。
function Sizzle(selector, context, results, seed) {
var match, elem, m, nodeType,
// QSA vars
i, groups, old, nid, newContext, newSelector;
if ((context ? context.ownerdocument || context : preferredDoc) !== document) {
setdocument(context);
}
context = context || document;
results = results || [];
if (!selector || typeof selector !== "string") {
return results;
}
if ((nodeType = context.nodeType) !== 1 && nodeType !== 9) {
return [];
}
// 若当前过滤的是HTML文档,且没有设定seed,则执行if内的语句体
if (documentIsHTML && !seed) {
if ((match = rquickExpr.exec(selector))) {
// Speed-up: Sizzle("#ID")
// 处理ID类型选择器,如:#ID
if ((m = match[1])) {
// 若当前上下文是一个document,则执行if内语句体
if (nodeType === 9) {
elem = context.getElementById(m);
// Check parentNode to catch when Blackberry 4.6
// returns
// nodes that are no longer in the document #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
if (context.ownerdocument
&& (elem = context.ownerdocument.getElementById(m))
&& contains(context, elem) && elem.id === m) {
results.push(elem);
return results;
}
}
// Speed-up: Sizzle("TAG")
// 处理Tag类型选择器,如:SPAN
} else if (match[2]) {
push.apply(results, context.getElementsByTagName(selector));
return results;
// Speed-up: Sizzle(".CLASS")
} else if ((m = match[3]) && support.getElementsByClassName
&& context.getElementsByClassName) {
push.apply(results, context.getElementsByClassName(m));
return results;
}
}
// QSA path
if (support.qsa && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
nid = old = expando;
newContext = context;
// 若context是document,则newSelector取自selector,否则为false
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
if (nodeType === 1 && context.nodeName.toLowerCase() !== "object") {
groups = tokenize(selector);
if ((old = context.getAttribute("id"))) {
nid = old.replace(rescape, "\$&");
} else {
context.setAttribute("id", nid);
}
nid = "[id='" + nid + "'] ";
// 重新组合新的选择器
i = groups.length;
while (i--) {
groups[i] = nid + toSelector(groups[i]);
}
newContext = rsibling.test(selector) && context.parentNode
|| context;
newSelector = groups.join(",");
}
if (newSelector) {
try {
// 将querySelectorAll获取的结果并入results,而后返回resulsts
push.apply(results, newContext
.querySelectorAll(newSelector));
return results;
} catch (qsaError) {
} finally {
if (!old) {
context.removeAttribute("id");
}
}
}
}
}
// All others
// 除上述快捷方式和调用querySelectorAll方式直接获取结果外,其余都需调用select来获取结果
return select(selector.replace(rtrim, "$1"), context, results, seed);
}
各位朋友,若觉得写得不错,帮我顶一下,给点动力,多谢!



