Ajax 板


LINE

也可以參考 http://ithelp.ithome.com.tw/question/10090810 ----------------------------------- ----------------------------------- 基本上 selector 嚴格分類來講有相當多種, slibing / parent ...etc 可以看這裡有分類 http://api.jquery.com/category/selectors/ CSS 提供給我們的那些相信大家都不陌生, ID(#)/Tag/class(.)/attr([])/child(>) ...etc 其中這次我要介紹的是, 一些算是比較不屬於 css3 規範的異類 selector , 大家可能常用(至少我常用),但是不見得知道他的運作模式, 這裡我們就是要來告訴你他是什麼。:) jQuery 的 selector 其實暗藏很多我們不知道的玄機, 我會盡量再多介紹一些。 ------- ok 不賣關子,我們開始談主題。 大家有沒有用過 pseudo selector ,像是這個範例? ----------------------------------- <div class="test"></div> <div class="test" style="display:none"></div> <div class="test" style="display:none"></div> <script> alert($(".test:visible").length); </script> ----------------------------------- Runnable sample : http://jsfiddle.net/GGRD6/ ":visible" selector,我相信大家都知道這不是 css 規格,但是它會動。:) 這種冒號開頭的選擇器,jQuery 稱之為虛擬選擇器。 (其實還再細分出一種是 pos selector 如 :eq / :lt / :odd ..etc ,剩下的都稱為 pseudo selector, 但這裡我先統稱為 pseudo selector 以便說明,原理是相近的。) 這時候我們就會需要來看看 jQuery 官方文件: http://api.jquery.com/visible-selector/ ----------------------------------- Because :visible is a jQuery extension and not part of the CSS specification, queries using :visible cannot take advantage of the performance boost provided by the native DOM querySelectorAll() method. To achieve the best performance when using :visible to select elements, first select the elements using a pure CSS selector, then use .filter(":visible"). ----------------------------------- (不負責翻譯) ----------------------------------- 因為 :visible 是一個 jQuery extension 而非 CSS 規格,使用 :visible 查詢時, 將無法利用到原生的 querySelectorAll() 函式,會比較慢。 要獲得最好效能,建議是先使用純 css 查詢再使用 filter 進行過濾。 ----------------------------------- 重要的是這裡印證虛擬選擇器可能都不是 css 官方規格, 這裡他同時說兩件我們需要知道的事情,但效能部份我們先不管, 我們文末會回頭再談,我們先介紹虛擬選擇器的原理。 為了說明,我想 :visible 一個例子是不夠的, 我再舉另一個例子 ":contains()" 好了, 這也是相當常見的例子,尋找指定元素內有包含特定字串的。 ----------------------------------- <div> <div class="test" style="display:none">I am a div </div> <div class="test" style="display:none"> I am also div </div> <div class="test" style="display:none">I am still a div </div> </div> <script> $(document.body).append(".test:contains('div') #=> "+ $(".test:contains('div')").length +"<br />"); $(document.body).append(".test:contains('still') #=> "+ $(".test:contains('still')").length +"<br />"); </script> ----------------------------------- 將會輸出 .test:contains('div') #=> 3 .test:contains('still') #=> 1 runnable sample http://jsfiddle.net/GGRD6/1/ 官方文件 http://api.jquery.com/contains-selector/ ---- 當然還有 :not 這個一定是不可少的。 ----------------------------------- <div> <div class="test test1" style="display:none">I am a div </div> <div class="test test2" style="display:none"> I am also div </div> <div class="test test3" style="display:none">I am still a div </div> </div> <script> $(document.body).append(".test:not('.test1') #=> "+ $(".test:not('.test1')").length +"<br />"); $(document.body).append(".test:not('.test1,.test2') #=> "+ $(".test:not('.test1,.test2')").length +"<br />"); </script> ----------------------------------- 輸出 .test:not('.test1') #=> 2 .test:not('.test1,.test2') #=> 1 官方文件 http://api.jquery.com/not-selector/ ---------------------------- 你一定很好奇為什麼我要特別介紹這個,我可以一個一個作 selector 的介紹, 為什麼要介紹「pseudo selector 」,他有什麼好介紹的? 除了效能議題以外,其實我更重視的是他實作的邏輯, 我曾經很好奇 jQuery 是怎麼實作的而翻過很多次他的原始碼, 而其中這一個是我特別有印象的。:) 他有趣的地方在於一是實作跟虛擬選擇器的對應,另外就是他的可擴充性。 以我們 JS developer 來講, 碰到 selelector 這種帶著規則的「字串」東西其實蠻沒轍的, 他又不是 call 一個純 js function , 你如果想 trace 也要多繞好幾圈才看的懂。 而 pseudo selector 的條件定義呢, 就由 jQuery.expr.filters 跟 jQuery.expr.setFilters (for pos selectors) 掌管, 所以你可以翻原始碼,也可以用這種方式找出所有虛擬選擇器: ----------------------------------- var filters = jQuery.expr.filters; for(var i in filters ){ $(document.body).append(i+" #=> "+ filters[i].toString()+"<br /><br />"); } $(document.body).append( "<div style='color:red;'>setFilters </div><br />"); filters = jQuery.expr.setFilters; for(var i in filters ){ $(document.body).append(i+" #=> "+ filters [i].toString()+"<br /><br />"); } ----------------------------------- 因為 details 有點多,想看細節的實作的可以移步 XD http://jsfiddle.net/yAAqD/ 翻翻 jQuery 1.7.2 的 4565 ~ 4686 行程式碼~(這只是其中部份。) 你會發現他基本上流程是這麼作: 1.先檢查是不是 pos selector ,是的話,就跑 jQuery.expr.setFilters 出來作 filter。 (:nth , :eq, :gt, :lt, :first, :last, :even, :odd ) 2.如果不是,就找 jQuery.expr.filters 如果後面還有跟其他 selector ,會再套疊後續的 operator 去做查詢。 --- 你可能會好奇,如果我給 $(".test:myfilter") 會發生什麼事情,答案是會噴 error: Syntax error, unrecognized expression: myfilter --- 所以理論上要擴充一個新的 filter , 直接擴充 jQuery.expr.filters 就可以了。 (如果你要擴充 set selector ,要改比較多東西,有興趣再問吧XD) 舉個例子,我今天比較機車,我想留 id 裡面, 有包含 tony 的元素,我可以這樣實作。 ----------------------------------- jQuery.expr.filters.isTony = function(elem){ return elem.id && elem.id.indexOf("tony") != -1; } //query with the pseudo selector //$("div:isTony") ----------------------------------- Sample http://jsfiddle.net/LMBgN/ 至於效能,基本上就如官網文件所說。 基本上 "查詢" ($(selector) 或 $parent.find(selector)) , 能不用虛擬 selector 就不該用; 而"過濾" ($set.filter(selector) or $set.is(selector )) 就很適合用。:) ----------------------------------- 文末的文末,補個題外話,我一直很訝異的是, jQuery mobile 是用這麼髒的方式, 來實作他們需要的內部用 pseudo selector。:P 有時候看看別人的實作,想想背後的理由,也是蠻有意思的。:P ----------------------------------- // Monkey-patching Sizzle to filter the :jqmData selector var oldFind = $.find, jqmDataRE = /:jqmData\(([^)]*)\)/g; $.find = function( selector, context, ret, extra ) { selector = selector.replace( jqmDataRE, "[data-" + ( $.mobile.ns || "" ) + "$1]" ); return oldFind.call( this, selector, context, ret, extra ); }; ----------------------------------- 這篇因為想睡了講的比較亂,有興趣/疑問歡迎發問。:) -- Life's a struggle but beautiful. --



※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.25.56.138 ※ 編輯: TonyQ 來自: 114.25.56.138 (04/16 00:57) ※ 編輯: TonyQ 來自: 114.25.56.138 (04/16 00:57)
1F:推 coldollsheep:不錯喔 04/16 10:43
2F:推 davidsky:UI.widget有實作widget的pseudo selector如':ui-tabs' 04/17 00:52
3F:→ davidsky:有段時間一直在用這個來快速找到widget...後來發現真的 04/17 00:53
4F:→ davidsky:很慢XD 全部換掉 04/17 00:53
5F:→ davidsky:但是有這功能出發點是不錯的 04/17 00:53
6F:→ TonyQ:我猜這就是為什麼 jquery mobile 這樣作 04/17 01:49
7F:→ TonyQ:因為它走回 attr selector 還是可以用到 qsa 04/17 01:49







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:Gossiping站內搜尋

TOP