jquery 選擇器引擎sizzle淺析
更新時(shí)間:2013年02月06日 15:26:35 作者:
用jquery的大概有一年了,只知道$(selector),其內(nèi)部選擇器是如何實(shí)現(xiàn)并不完全不清晰,汗顏啊于是看了jquery的源碼,jquery用的選擇器的引擎是sizzle,感興趣的朋友可以了解下,或許本文對(duì)你有所幫助
I'm sorry!我用jquery的大概有一年了,只知道$(selector),其內(nèi)部選擇器的流程走向完全不清晰!于是看了jquery的源碼,jquery用的選擇器的引擎是sizzle,是jquery的作者另一開源項(xiàng)目,在github上面有,號(hào)稱最快的dom選擇器!不到2000行代碼。
上面說了不是很精彩的開場白,我么來個(gè) for example: $('.test') 在jquery的流程是怎么走的呢?
1.首先會(huì)做如下的判斷
/**
*關(guān)于 querySelectorAll函數(shù)
*返回當(dāng)前文檔中匹配一個(gè)特定選擇器的所有的元素
*var nodelist = element.querySelectorAll("div.test");
*支持瀏覽器 ie8+,Chrome,Firefox(3.5)
* 如果你不清楚可以google 一下
*/
if ( document.querySelectorAll ) {
(function(){
var oldSizzle = Sizzle,
div = document.createElement("div"),
id = "__sizzle__";
div.innerHTML = "<p class='TEST'></p>";
// Safari can't handle uppercase or unicode characters when
// in quirks mode.
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
return;
}
Sizzle = function( query, context, extra, seed ) {
//使用querySelectorAll 來查詢
}
}
如果你的瀏覽器是ie8+ 或者 谷歌,直接通過內(nèi)置的querySelectorAll(".test")返回dom結(jié)構(gòu)。 如果你使用是ie6,那么下面事情發(fā)生了
2. 不支持querySelectorAll 就會(huì)啟動(dòng)內(nèi)部 sizzle。下面是流程
/**
.sizzle 通過
chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g
這個(gè)正則進(jìn)行匹配,
.把我們傳來的參數(shù)'.test',匹配成'.test' 放到數(shù)組
.檢測瀏覽器是否支持getElementsByClassName 如果支持,則通過此函數(shù)返回dom,如果不支持此函數(shù)則 context.getElementsByTagName( "*" ) ,通過上下文把所有的元素選出來,在通過循環(huán),選擇className = 'test' 的元素,放入數(shù)組返回dom。
*/
ok,以上是$('.test')的流程,如果你很迷惑,你可以看看源碼,調(diào)試一下。
關(guān)于sizzle的選擇器
個(gè)人認(rèn)為,sizzle選擇器是增強(qiáng)版的querySelectorAll 函數(shù), 因?yàn)閝uerySelectorAll 不支持 'div.test :eq(1)' 這樣的selector 和css3選擇!
當(dāng)你的selector里面不出現(xiàn)nth|eq|gt|lt|first|last|even|odd 這樣的字符時(shí)候, 從右向左,所謂的從右向左,比如 $('div img') 首先會(huì)把所有的img 選出來,通過parent 是div 進(jìn)行過濾 。 這樣很高效的原因是只進(jìn)行一次dom的查詢!
當(dāng)你selector 出現(xiàn)了'eq(1)' 這樣的字符的時(shí)候,就變正常了,從左向右!這是因?yàn)橐獙?duì)結(jié)果集進(jìn)行過濾。
思考
$('div img:eq(0)') 與 $('div img').first() 哪個(gè)效率高? 個(gè)人認(rèn)為 后一個(gè)高一些,因?yàn)?第一從左向右效率低下!沒有測試過!理論推導(dǎo)!
今天大致看了下流程,具體的代碼沒怎么細(xì)研究!這里面好的思想值得學(xué)習(xí)和吸收
歡迎拍磚
上面說了不是很精彩的開場白,我么來個(gè) for example: $('.test') 在jquery的流程是怎么走的呢?
1.首先會(huì)做如下的判斷
復(fù)制代碼 代碼如下:
/**
*關(guān)于 querySelectorAll函數(shù)
*返回當(dāng)前文檔中匹配一個(gè)特定選擇器的所有的元素
*var nodelist = element.querySelectorAll("div.test");
*支持瀏覽器 ie8+,Chrome,Firefox(3.5)
* 如果你不清楚可以google 一下
*/
if ( document.querySelectorAll ) {
(function(){
var oldSizzle = Sizzle,
div = document.createElement("div"),
id = "__sizzle__";
div.innerHTML = "<p class='TEST'></p>";
// Safari can't handle uppercase or unicode characters when
// in quirks mode.
if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
return;
}
Sizzle = function( query, context, extra, seed ) {
//使用querySelectorAll 來查詢
}
}
如果你的瀏覽器是ie8+ 或者 谷歌,直接通過內(nèi)置的querySelectorAll(".test")返回dom結(jié)構(gòu)。 如果你使用是ie6,那么下面事情發(fā)生了
2. 不支持querySelectorAll 就會(huì)啟動(dòng)內(nèi)部 sizzle。下面是流程
復(fù)制代碼 代碼如下:
/**
.sizzle 通過
chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g
這個(gè)正則進(jìn)行匹配,
.把我們傳來的參數(shù)'.test',匹配成'.test' 放到數(shù)組
.檢測瀏覽器是否支持getElementsByClassName 如果支持,則通過此函數(shù)返回dom,如果不支持此函數(shù)則 context.getElementsByTagName( "*" ) ,通過上下文把所有的元素選出來,在通過循環(huán),選擇className = 'test' 的元素,放入數(shù)組返回dom。
*/
ok,以上是$('.test')的流程,如果你很迷惑,你可以看看源碼,調(diào)試一下。
關(guān)于sizzle的選擇器
個(gè)人認(rèn)為,sizzle選擇器是增強(qiáng)版的querySelectorAll 函數(shù), 因?yàn)閝uerySelectorAll 不支持 'div.test :eq(1)' 這樣的selector 和css3選擇!
當(dāng)你的selector里面不出現(xiàn)nth|eq|gt|lt|first|last|even|odd 這樣的字符時(shí)候, 從右向左,所謂的從右向左,比如 $('div img') 首先會(huì)把所有的img 選出來,通過parent 是div 進(jìn)行過濾 。 這樣很高效的原因是只進(jìn)行一次dom的查詢!
當(dāng)你selector 出現(xiàn)了'eq(1)' 這樣的字符的時(shí)候,就變正常了,從左向右!這是因?yàn)橐獙?duì)結(jié)果集進(jìn)行過濾。
思考
$('div img:eq(0)') 與 $('div img').first() 哪個(gè)效率高? 個(gè)人認(rèn)為 后一個(gè)高一些,因?yàn)?第一從左向右效率低下!沒有測試過!理論推導(dǎo)!
今天大致看了下流程,具體的代碼沒怎么細(xì)研究!這里面好的思想值得學(xué)習(xí)和吸收
歡迎拍磚
相關(guān)文章
jQuery基于隨機(jī)數(shù)解決中午吃什么去哪吃問題示例
這篇文章主要介紹了jQuery基于隨機(jī)數(shù)解決中午吃什么去哪吃問題,涉及jQuery基于事件響應(yīng)及隨機(jī)數(shù)動(dòng)態(tài)操作頁面元素相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-12-12基于jQuery的可以控制左右滾動(dòng)及自動(dòng)滾動(dòng)效果的代碼
迷上jQuery,相對(duì)于原生JavaScript,它是如此的美妙.也因此,促使我更加的努力的研習(xí)原生JavaScript.2010-07-07jqGrid 學(xué)習(xí)筆記整理——進(jìn)階篇(一 )
這篇文章主要介紹了jqGrid 學(xué)習(xí)筆記整理——進(jìn)階篇(一 )的相關(guān)資料,需要的朋友可以參考下2016-04-04用jQuery技術(shù)實(shí)現(xiàn)Tab頁界面之二
這個(gè)tab頁是把數(shù)據(jù)全部取回來再顯示,所以沒有數(shù)據(jù)緩存的特點(diǎn)。但是因?yàn)閿?shù)據(jù)全部是顯示的html代碼,所以對(duì)搜索引擎是友好的,也許對(duì)seo有好處。2009-09-09jquery.cookie.js 操作cookie實(shí)現(xiàn)記住密碼功能的實(shí)現(xiàn)代碼
jquery.cookie.js操作cookie實(shí)現(xiàn)記住密碼功能,很簡單很強(qiáng)大,喜歡的朋友可以參考下。2011-04-04jquery實(shí)現(xiàn)側(cè)邊彈出的垂直導(dǎo)航
這篇文章主要介紹了jquery動(dòng)畫特效結(jié)合css實(shí)現(xiàn)側(cè)邊彈出的垂直導(dǎo)航的方法及代碼分享,需要的朋友可以參考下2014-12-12jquery利用ajax調(diào)用后臺(tái)方法實(shí)例
這篇文章介紹了jquery利用ajax調(diào)用后臺(tái)方法實(shí)例,有需要的朋友可以參考一下2013-08-08