博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
sizzle源码分析 (2)ID 类 tag querySelectorAll 快速匹配
阅读量:4677 次
发布时间:2019-06-09

本文共 5038 字,大约阅读时间需要 16 分钟。

不是所有的选择器都需要去分词,生成相应的匹配函数,这样流程比较复杂,当浏览器具备原生的方法去匹配元素是,没有理由不优先匹配,下面看看进入Sizzle后,它是怎么优先匹配这些元素的:

 
function Sizzle( selector, context, results, seed ) {    /*    执行$("ul.list>li span:eq(1)")时,递归第二次时,    selector    "ul.list>li span"    */    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 [];    }    if ( documentIsHTML && !seed ) {        // Shortcuts        if ( (match = rquickExpr.exec( selector )) ) {
//先看是不是简单的ID选择器 TAG选择器 类选择器 // Speed-up: Sizzle("#ID") if ( (m = match[1]) ) { 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") } 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 是否支持document.querySelectorAll if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { nid = old = expando; newContext = context; 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 { push.apply( results, newContext.querySelectorAll( newSelector ) ); return results; } catch(qsaError) { } finally { if ( !old ) { context.removeAttribute("id"); } } } } } // All others //去除选择器首位空格,并进入select函数 return select( selector.replace( rtrim, "$1" ), context, results, seed );}

先看:rquickExpr

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
当执行:match = rquickExpr.exec( selector ),产生一个长度为4的数组:其中match[1]ID匹配项,match[2]为tag匹配项,match[3]为类匹配项 比如:当执行$("div")时, match=["div", undefined, "div", undefined] 接下来就判断具体符合哪种选择器了,然后用原生方法直接获得。 如果不是上述三种选择器,那么开始试探querySelectorAll:
// QSA path 是否支持document.querySelectorAll        if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {

然后就就开始try尝试:

if ( newSelector ) {                try {                    push.apply( results,                        newContext.querySelectorAll( newSelector )                    );                    return results;                } catch(qsaError) {                } finally {                    if ( !old ) {                        context.removeAttribute("id");                    }                }            }

如果成功就返回results

转载于:https://www.cnblogs.com/mufc-go/p/3301269.html

你可能感兴趣的文章
多张照片拍摄、图片浏览
查看>>
html(5) css
查看>>
Azure Web连接到Azure MySql Db
查看>>
《麻辣江湖》即将上线!
查看>>
Mybatis中mapper.xml文件判断语句中的单双引号问题
查看>>
frameset和frame
查看>>
饥饿的小易(规律,同余大数)
查看>>
ats透明代理
查看>>
PHP 小代码
查看>>
2016/03/16 codes
查看>>
2018年7月21日工作总结
查看>>
Linux shell 命令判断执行语法 ; , && , ||
查看>>
vim代码格式化插件clang-format
查看>>
What does the dot after dollar sign mean in jQuery when declaring variables?
查看>>
windows registry
查看>>
jquery 动画总结(主要指效果函数)
查看>>
【BZOJ4155】[Ipsc2015]Humble Captains
查看>>
【事件】阻止事件的冒泡
查看>>
mac os 安装 geckodriver
查看>>
【数据分析 R语言实战】学习笔记 第十一章 对应分析
查看>>