日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jQuery选择器引擎和Sizzle介绍

發(fā)布時間:2024/4/15 编程问答 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jQuery选择器引擎和Sizzle介绍 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
jQuery選擇器引擎和Sizzle介紹

首先介紹一下什么是Sizzle:

Sizzle是一個純javascript CSS選擇器引擎。jquery1.3開始使用sizzle,Sizzle一反傳統(tǒng)采取了相反的Right To Left的查詢匹配方式,效率提高.Sizzle是jQuery作者John Resig新寫的DOM選擇器引擎,速度號稱業(yè)界第一.Sizzle完全獨立于jQuery,若不想用jQuery,你可只用Sizzle實現(xiàn),壓縮3K多http://url.cn/J73IkN

這是一篇yleo77的關(guān)于介紹jQuery Sizzle選擇器的文章,由其和obility共同完成?,F(xiàn)在收藏在此學(xué)習(xí)研究。

在文中,我們試圖用自己的語言配以適量的代碼向讀者展現(xiàn)出Sizzle在處理選擇符時的流程原理,以及末了以少許文字給你展示出如何借用Sizzle之手實現(xiàn)自定義選擇器(也許更標準的叫法叫做過濾符)和它與YUI 選擇器的大致比較。

前序

?

jQuery相比1.2的版本,在內(nèi)部代碼的構(gòu)造上已經(jīng)出現(xiàn)了巨大的變化,其之一便是模塊的分發(fā).我記得09年在jquery 9月開的一次大會上 john放出的一張ppt上 也指出了當前的jquery下一步目標,不僅僅是除了sizzle選擇器的分離,屆時core,attribute,css以及manipulation,包括event也都會獨立成單獨的js文件.(1.4的文件結(jié)構(gòu),其實已經(jīng)分成單獨的16個模塊的組成)

隨著jQuery被用來構(gòu)建web app的場合愈來愈多,它的性能自然受到了大部分開發(fā)者的高度關(guān)注,它的內(nèi)部實現(xiàn)機理又是如何,比如選擇器的實現(xiàn)。

Sizzle,作為一個獨立全新的選擇器引擎,出現(xiàn)在jQuery 1.3版本之后,并被John Resig作為一個開源的項目,可以用于其他框架:Mool, Dojo,YUI等。

好了,現(xiàn)在來看為什么Sizzle選擇器如此受歡迎,使它能夠在常用dom匹配上都快于其他選擇器而讓這些框架們都垂青于它。

?

概要

一般選擇器的匹配模式(包括jq1.2之前),都是一個順序的思維方式,在需要遞進式匹配時,比如$(‘div span’) 這樣的匹配時,執(zhí)行的操作都是先匹配頁面中div然后再匹配它的節(jié)點下的span標簽,之后返回結(jié)果。

Sizzle則采取了相反Right To Left的實現(xiàn)方式,先搜尋頁面中所有的span標簽,再其后的操作中才去判斷它的父節(jié)點(包括父節(jié)點以上)是否為div,是則壓入數(shù)組,否則pass,進入下一判斷,最后返回該操作序列。

性能上得到了提升,對比性能參考下圖

?

另外,在很多細節(jié)上也進行了優(yōu)化。

淺析源碼

在探索 $ 符 和 Sizzle的協(xié)同工作原理前,先引用一張圖片

?

?

開始吧。($符在這里不作過多的介紹).

當我們給$符傳遞進一個參數(shù)(也可能是多個)時,此時它會根據(jù)參數(shù)的類型(domElement | string | fn | array)進入不同的流程,在此,重點看 string 類型的處理,因為只有它才可以觸發(fā)Sizzle。首先調(diào)用正則匹配看是否為創(chuàng)建dom節(jié)點的操作,然后看是否為簡單id匹配,這一步也由正則匹配完成,否則進入jQuery.fn.find()函數(shù),由此進入Sizzle的天地。

當進入Sizzle時,一般情況下會配備三參:所要匹配的選擇符,上下文,匹配的結(jié)果集。調(diào)用正則對傳入的selector做一次”預(yù)匹配”.

var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,

讓我們看一下一個簡單選擇器的實現(xiàn)過程:比如 div > p。我們要先找出符合條件的div[div],再找出符合條件的p[p],最后在上下文里[div]過濾出符合條件”>”的p[p];抽象一點的說法就是:在已知的上下文里,根據(jù)關(guān)系找出相應(yīng)的節(jié)點。他們靠關(guān)系聯(lián)系起來。那么對于選擇器的操作也就是根據(jù)關(guān)系來分組。一次次縮小上下文,直到找出符合條件的節(jié)點。

回到我們的話題,還是先看看這個令人費解的正則,相信你會有更好的分析方法,但是眼下,我還是一點點的拆分,讓它表達的更清晰一點。先按照分組拆,即():

((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])

?

(\s*,\s*)?

?

((?:.|\r|\n)*)

第一行還是有點長,用’|'拆分它:

1. (?:\((?:\([^()]+\)

2.[^()]+)+\)

3. \[(?:\[[^[\]]*\]

4. [^[\]]+)+\]|\\.

5.[^ >+~,(\[]+)+

6.[>+~]

對于如div > p。會得到數(shù)組結(jié)果['div','>','p']。

對于更復(fù)雜的選擇器,如div.classname > p.classname。會得到結(jié)果['div.classname','>','p.classname']。

對于具有合并的‘,’,只是遞歸調(diào)用下獲取結(jié)果再合并而已。過程開始變得簡單起來。

對于普通的解析過程,我們遵循著從左到右的順序即可完成我們的目標。

讓我們總結(jié)下步驟:

1.先查找頁面上所有的div?

?

2.循環(huán)所有的div,查找每個div下的p ?

?

3.合并結(jié)果

Sizzle用了截然相反的步驟:

1.先查找頁面上所有的p?

?

2.循環(huán)所有的p,查找每個p的父元素

? 1.如果不是div,遍歷上一層。

? 2.如果已經(jīng)是頂層,排除此p。

? 3.如果是div,則保存此p元素。

由子元素來查找父元素,能得到更好的效率???#xff0c;打破常規(guī)思維后不僅步驟更簡單了,而且效率上也得到了些許提升。

所有的選擇器都可以這樣解析嗎?不是,采用right -> left的順序是有前提條件的:沒有位置關(guān)系的約束。

比如如下這段html:

<div> <p id="p1">p1content <p id="p2">p2content </div> <div> <p id="p3">p3content <p id="p4">p4content </div>

對于選擇器:$(“div p:first”)只會返回["#p1"]

而$(“div p:first-child”)則返回["#p1", "#p3"]

兩者的區(qū)別在于位置filter的結(jié)果依賴于它前面的selector解析的結(jié)果,而其它 filter,只依賴于當前元素本身,就可以判斷它是否滿足filter。

那Sizzle是通過什么來判定進入哪一個流程呢,答案是origPOS的正則匹配,origPos指向了Expr中match對象的POS屬性,而POS中存儲了五花八門的位置類約束,如下:

/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/ ? ? //POS的值

這樣一來,第一步的流程判斷就已明朗。

當處于1的情況時:

首先根據(jù)需要對當前處理的A數(shù)組元素進行一系列修正操作(Expr.relative主刀)。然后調(diào)用posProcess函數(shù)對修復(fù)后的元素進行匹配.

其中,還需一層判斷,如果有層級約束,eg ‘>,’:input’ 會轉(zhuǎn)化為 ‘> :input’,因為在最初調(diào)用chunker進行預(yù)匹配的時候,這些是會被分割為單個數(shù)組元素的,但在這里需要將它們做一次合并,這是由posProcess所處理的數(shù)據(jù)格式所決定的

源碼片段a: — posProcess函數(shù)匹配核心

//如果存在偽類選擇符,從selector中移除,并保存在later中 // 這樣一來,匹配對象便分離出來:selector(簡單選擇符存儲器)和later(偽類選擇符存儲器)。 while ( (match = Expr.match.PSEUDO.exec( selector )) ) { ? ? later += match[0]; ? ? selector = selector.replace( Expr.match.PSEUDO, "" ); } //構(gòu)造selector,并調(diào)用Sizzle進行匹配,將結(jié)果存儲在tmpSet中 selector = Expr.relative[selector] ? selector + "*" : selector; for ( var i = 0, l = root.length; i < l; i++ ) { ? ? Sizzle( selector, root[i], tmpSet ); } // 最后便是filter的過濾 return Sizzle.filter( later, tmpSet );

源碼片段b: — 對預(yù)匹配后的數(shù)組A中元素的處理

//這個為特例,被正則分割的A數(shù)組長度為2,則合并數(shù)組元素,上下文則原封不動為Sizzle傳遞進來的context。 if ( parts.length === 2 &amp;&amp; Expr.relative[ parts[0] ] ) { ? ? // 完成一次匹配, 由posProcess 內(nèi)部調(diào)用 filter進行匹配 ? ? // 但在匹配前,完成了一次連接選擇符的操作 ? ? // 存入set,注 set 當前還不是最終的結(jié)果,其這里的set和上面的tmpSet一樣,都是一個"暫時性"的結(jié)果集 ? ? set = posProcess( parts[0] + parts[1], context );

源碼片段c: — 如果存在位置約束關(guān)系, 正向匹配。

set = Expr.relative[ parts[0] ] ? ? ? [ context ] : ? ? // 否則對隊列首元素進行一次簡單匹配操作 ? ? Sizzle( parts.shift(), context );

分析Expr.relative,可以看出,它包含了4種dom元素間關(guān)系的判斷,分別是 “+”, “>”, “”, “~”

每一輪的匹配,都會先判斷A數(shù)組的首元素是不是代表tag間關(guān)系符(+,>等) ,而做后續(xù)處理.同時對A數(shù)組進行循環(huán),依次做類似的處理

源碼片段d — 對A數(shù)組(parts)的循環(huán)處理及后續(xù)

while ( parts.length ) { ? ? // 依次對 所匹配到的 數(shù)組中元素進行 遞進匹配 ? ? selector = parts.shift(); ? ? // ? '>' ?-> '>input' 的形式 ? ? if ( Expr.relative[ selector ] ) ? ? ? ? selector += parts.shift(); ? ? set = posProcess( selector, set );

當處于2的情況時:

就有著不同之處,先看小片代碼

源碼片段e: — 根據(jù)當前流程設(shè)置ret(兩種情況)

//為ret綁定正確的返回值 var ret = seed ? ? ? ? //seed 為上一次調(diào)用sizzle返回值, 即前文中提到的set|tmpset ? ? //將預(yù)匹配后的A數(shù)組(parts)中的最后元素設(shè)置為ret的expr屬性,set屬性設(shè)為上一次匹配的結(jié)果集。 ? ? { expr: parts.pop(), set: makeArray(seed) } : ? ? //如果是第一次調(diào)用,則進行匹配操作,調(diào)用find函數(shù) ? ? // 以parts數(shù)組最末元素為當前選擇符,進行匹配操作,同時設(shè)置與之相關(guān)的context ? ? Sizzle.find( parts.pop(), parts.length === 1 &amp;&amp; context.parentNode ? context.parentNode : context, isXML(context) );

2的情況為一般邏輯處理,從這小段代碼便可得到Sizzle的匹配機制,每一次的調(diào)用都以數(shù)組末元素為基準,以上一次(或預(yù)設(shè)context)為上下文約束關(guān)系以右到左的匹配,最后返回匹配結(jié)果。結(jié)合了DOM結(jié)構(gòu)的特性,性能上也得到了大幅的提升。

我們知道選擇器的類型是有效率差別的,id選擇器效率最高,其次是class、name、tag、最后是最差的*表達式。在Sizzle.find函數(shù)中,會按照這個效率的順序查找元素,如果沒有id就找class,依次下去。當然,class的支持需要方法getElementsByClassName。如果沒有,就只好從id跳到name。

if ( document.getElementsByClassName &amp;&amp; document.documentElement.getElementsByClassName ) (function(){ ? ? // ... ? ? // 如果支持直接獲取,則將獲取class的方法 直接添加進 Expr.order中 ? ['ID', 'NAME', 'TAG'] ? ? Expr.order.splice(1, 0, "CLASS"); ? ? //同時在find中追加對class的獲取 ? ? Expr.find.CLASS = function(match, context, isXML) { ? ? ? ? if ( typeof context.getElementsByClassName !== "undefined" &amp;&amp; !isXML ) { ? ? ? ? ? ? return context.getElementsByClassName(match[1]); ? ? ? ? } ? ? }; })();

在Sizzle.find函數(shù)中,做了一系列的邏輯判斷,來保證返回結(jié)果的正確性,首先在進入find時,保證了expr不為空的,然后根據(jù)表達式類型(id|name|tag|class?)來選擇與之對應(yīng)的匹配分支進行實現(xiàn),最后再做適當?shù)氖瘴补ぷ?#xff0c;將返回結(jié)果定義為對象,來移交給filter,完成整個流程。

源碼片段f: — find 函數(shù)核心

//order: [ "ID", "NAME", "TAG" ] // 當然,如果瀏覽器支持對class的直接獲取時,order中就會出現(xiàn)class的相關(guān)匹配規(guī)則 for ( var i = 0, l = Expr.order.length; i < l; i++ ) { ? ? var type = Expr.order[i], match; ? ? // 根據(jù) type 對所傳進來的expr 進行正則匹配 ? ? // match中通過正則限制了這三類匹配方式的條件。 ? ? // 1. ID: /#((?:[\w\u00c0-\uFFFF_-]|\\.)+)/, ? ? // 2. NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF_-]|\\.)+)['"]*\]/, ? ? // 3. TAG: /^((?:[\w\u00c0-\uFFFF\*_-]|\\.)+)/, ? ? if ( (match = Expr.match[ type ].exec( expr )) ) { ? ? ? ? var left = RegExp.leftContext; ? ? ? ? //保證返回結(jié)果的正確性,如果存在\,則刪除 ? ? ? ? if ( left.substr( left.length - 1 ) !== "\\" ) { ? ? ? ? ? ? match[1] = (match[1] || "").replace(/\\/g, ""); ? ? ? ? ? ? // 根據(jù)type調(diào)用 sizzle.selector.find方法獲取結(jié)果集。 ? ? ? ? ? ? set = Expr.find[ type ]( match, context, isXML ); ? ? ? ? ? ? if ( set != null ) { ? ? ? ? ? ? ? ? //如果匹配成功,刪除已經(jīng)匹配的expr ? ? ? ? ? ? ? ? expr = expr.replace( Expr.match[ type ], "" ); ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? } ? ? ? ? } ? ? } } return {set: set, expr: expr}; };

在所返回的對象中,expr的作用便是為了輔佐filter這把大器所需要完成任務(wù)的工具,到此就可以調(diào)用Sizzle.filter對ret.set再做一次精確匹配(匹配規(guī)則即ret.expr),以及tag間的位置約束關(guān)系的匹配(這部分同1中類似).

源碼片段g: — 和源碼片段d有類似之處。不作詳述

? ? while ( parts.length ) { ? ? ? ? var cur = parts.pop(), pop = cur; ? ? ? ? // 是否存在 類似這樣的匹配 eg: ?'+', ?'>'等 ? ? ? ? if ( !Expr.relative[ cur ] ) { ? ? ? ? ? ? cur = ""; ? ? ? ? } else { ? ? ? ? ? ? //如果存在層間關(guān)系的約束 ?則修復(fù) cur 和pop的指向 ? ? ? ? ? ? // eg ?['div', '+', 'span'] => ? pop = div; ?cur = '+'; 并進入 relative的匹配。 ? ? ? ? ? ? pop = parts.pop(); ? ? ? ? } ? ? ? ? // ?確保擁有上下文 代碼略過 ? ? ? ? Expr.relative[ cur ]( checkSet, pop, isXML(context) ); ? ? }

之后便接近sizzle尾聲:結(jié)果集的處理(將所匹配的結(jié)果set 追加進 result中)。當然,如果有多表達式,便會再一次調(diào)用。

實例

以’div > span p span:last’這個選擇符為例,看看它的調(diào)用鏈是如何順次完成的。

根據(jù)對源碼的剖析,理解如下:

  • jquery.init -> jquery.prototype.find
  • 進入Sizzle(對xml的判斷) -> 設(shè)置parts數(shù)組等在匹配中所需要的元素 -> 根據(jù)數(shù)組長度以及調(diào)用origPos進行判斷,來決定進入哪個分支,在這個實例下進入分支1
  • 循環(huán)調(diào)用Sizzle進行匹配,將結(jié)果存入set中(因為在這一過程中是循環(huán)調(diào)用,所以對Sizzle的判斷也是需要多次,進入哪一分支當然也會是不一樣的,比如第二輪循環(huán)判斷則進入分支2中進行處理) ,對于>號的處理,也會將它合并在其后的span中,構(gòu)成新的選擇符 ‘>span’,然后進入Expr.relative進行匹配,同時調(diào)用posProcess。
  • 調(diào)用Sizzle.find 匹配除偽類以外的部分(即這里的選擇器不包含:last),首先會調(diào)用Expr.find的find方法來判斷是否為哪一類匹配,在這一實例中,為TAG匹配。
  • 對從4步中生成的對象進行過濾,匹配’>'(這一步的匹配是由Sizzle.filter觸發(fā),由Expr.relative完成),而在匹配’span:last’時則由posProcess來觸發(fā),設(shè)置later值(:first)以及selector(span),對span的匹配和4步驟一樣,重復(fù)匹配,而對:first的匹配則是第5步的重頭戲,也就是調(diào)用Sizzle.filter來完成, 由此便生成了最后的匹配結(jié)果。
  • 對于有‘,’這樣需要合并的選擇器,Sizzle在獲取結(jié)果后會按照文檔流進行排序。所以,你可能會遇到這樣的問題:把一個結(jié)果集append到新的節(jié)點后,新的節(jié)點可能不會按照你書寫的選擇器的順序出現(xiàn)。

    以上,可以得出以下結(jié)論:大致通過如下步驟來完成:

    1.對表達式分組。

    2.選擇合適的處理順序。

    3.在當前的上下文里過濾要找的節(jié)點。并更新上下文。重復(fù)這一過程,直到結(jié)尾。

    4.對結(jié)果排序,如果需要的話。

    5.返回結(jié)果數(shù)組。

    前向兼容

    querySelectorAll

    其實不止這一處,在Sizzle的API手冊中Internal部分的find 函數(shù)(與filter構(gòu)成了Sizzle的兩把寶劍),在傳遞進該方法的參數(shù)可以用querySelectorAll() (依賴于當前的瀏覽器執(zhí)行環(huán)境) 直接獲取時,它則直接調(diào)用該方法,既擁有了向前兼容的特性,又達到了速度的提升。

    雖然有些環(huán)境實現(xiàn)了方法querySelectorAll,但是會有bug。

    //如果當前document 支持 querySelectorAll方法,則將瀏覽器可以完成的匹配完全交給瀏覽器 if ( document.querySelectorAll ) (function(){ ? ? var oldSizzle = Sizzle; ? ? // 解決Safari bug 略過 ... ? ? Sizzle = function(query, context, extra, seed){ ? ? ? ? context = context || document; ? ? // 因為querySelectorAll 在domElement 節(jié)點上操作時,存在bug 所以多了這樣的判斷 ? ? // bug info: http://ejohn.org/blog/thoughts-on-queryselectorall/ ? ? ? ? if ( !seed &amp;&amp; context.nodeType === 9 &amp;&amp; !isXML(context) ) { ? ? ? ? ? ? return makeArray( context.querySelectorAll(query), extra ); ? ? ? ? } ? ? ? ? // querySelectorAll 可用則直接返回結(jié)果,否則才調(diào)用 sizzle ? ? ? ? return oldSizzle(query, context, extra, seed); ? ? }; ? ? // oldSizzle 方法追加進 新的 Sizzle 中 })();

    對于任何一個開發(fā)者,我想,若瀏覽器原生已提供了實現(xiàn)方法,他都不會去高效而求繁瑣吧。這一點在Sizzle中得到了充分的體現(xiàn),總是盡可能的使用相應(yīng)環(huán)境下已實現(xiàn)的原生方法。所以在IE的低版本中(比如IE6)Sizzle的表現(xiàn)更加出眾,在高級的瀏覽器中的對比卻沒有那么大的差別。

    擴展

    如何定義自己的選擇器呢.如果項目中頻繁使用某些過濾規(guī)則,是不是把它作為一個選擇器更有效呢。

    既然javascript的對象可以任意擴充,只要我們訪問得到,那么我們就可以很輕松得創(chuàng)建出自己的選擇器

    在jQuery.expr.filter對象中,有很多內(nèi)置的選擇器,比如 ‘disabled’,'text’,那我們就擴充它,比如,想尋找包含span的div元素

    // filter的簡寫 ?':' jQuery.expr[":"] = jQuery.expr.filters; $.extend($.expr[':'], { ? ? hasSpan: function(e) { ? ? ? ?return $(e).find('span').length > 0; ? ? } });

    這樣,我們就擁有了 ‘:hasSpan’ 的選擇器,使用當然和默認的一樣。

    //直接用就可以了 $('div:hasSpan')....

    比較

    再拾YUI3,在經(jīng)過大幅度變化,以全新姿態(tài)出現(xiàn),從選擇器上的執(zhí)行上效率不遜色于Sizzle幾毫,初看YUI時就一直對它的模塊細粒度化贊不絕口,但是從如我這樣的實用主義者的角度來看,選擇器就應(yīng)該是一個單獨的模塊,就如同jQuery分離而出的Sizzle。但在YUI term眼里,為了讓代碼的組織結(jié)構(gòu)看上去更加的理想化,更加具有”YUI3“的特色,將之在代碼結(jié)構(gòu)上又細分出一二三,比起Sizzle的簡潔,它顯得太過學(xué)院派。

    除此,在選擇器的擴展上,sizzle表現(xiàn)勝于YUI3 selector,在實現(xiàn)css1~css3選擇器的基礎(chǔ)上,又對常用的功能進行了擴展。比如對表單元素快捷操作。據(jù)我所知,開發(fā)者對這類型選擇器的使用頻率并不是想象中那么低。既然有了模塊的細分,為什么不將這部分作為一個可擴充性的功能點模塊融入框架中呢。Sizzle于開發(fā)者就如同一塊可口味佳的點心,滿足我們各式各樣的胃口,簡潔,不失其功能的強勁,這點非常值得稱道。

    總得來看,Sizzle與YUI就好象一個面向?qū)嶋H與理想主義的比較。這里沒有對錯之分,從不同角度來看,都能略窺其各自的禪意。前者從如何為開發(fā)者帶來便利的角度考慮,讓開發(fā)者實時覺得它的簡單可信賴。后者,也寄托了自己對web的構(gòu)想,如果瀏覽器原生全部支持css3-selector,那豈不是完全不用引入該模塊了,不過我想,真到那時候,各框架也都會有很大的變化了,只是我對這一天的到來抱有比較消極的態(tài)度,這是后話。

    總結(jié)

    本文從總體上討論了jQuery之Sizzle選擇器的實現(xiàn)原理,通過一個初步的流程分析,讓各位讀者對此有一個大致印象,毫無疑問,更深層次的匹配,也只是它的遞歸調(diào)用,再匹配而已。

    這里,沒有做與其他框架在效率上的比較,如果你還對它的效率還有所懷疑的話,你可以自行比較。

    如果你感興趣,更推薦你繼續(xù)去探索在1.4中著重優(yōu)化的api源碼,或許,會給你更多的啟示

    思考

    從jQuery的角度來講,Sizzle的出現(xiàn)隨之也帶來了web上的一些新的局面,在追求效率的同時,即使是這類單種子模式的庫也是需要將之分離開來,來設(shè)計成能夠獨立使用,獨立維護的引擎。

    從選擇器的角度來講,Sizzle這次算法的提升,我初步的結(jié)論是它結(jié)合了DOM這一特定的數(shù)據(jù)結(jié)構(gòu),使其每次的匹配能夠更精準,以此獲得引擎效率上的提升。

    我們可否多想想,在思維的開拓上能給我們留下多少財富。很多問題的解決,在換一種新的思維方式后,是不是常常會有柳暗花明的感覺呢。

    相關(guān)參考:

    W3C css selector:CSS1,CSS2,CSS3

    CSS Support History -Brian Wilson

    CSS Selectors and Pseudo Selectors and browser support – kimblim.dk

    Javascript CSS Selector Engine Timeline – Paul Irish

    Sizzle Documentation

    posted on 2017-05-06 13:38 玲兒靈 閱讀(...) 評論(...) 編輯 收藏

    轉(zhuǎn)載于:https://www.cnblogs.com/jymz/p/6816506.html

    超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術(shù)人生

    總結(jié)

    以上是生活随笔為你收集整理的jQuery选择器引擎和Sizzle介绍的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。