jQuery基礎---常規選擇器


內容摘要:

1.簡單選擇器

2.進階選擇器

3.高級選擇器

發文不易,轉載請注明出處!

jQuery 最核心的組成部分就是:選擇器引擎。它繼承了 CSS 的語法,可以對 DOM 元素的標簽名、屬性名、狀態等進行快速准確的選擇,並且不必擔心瀏覽器的兼容性。jQuery選擇器實現了 CSS1~CSS3 的大部分規則之外,還實現了一些自定義的選擇器,用於各種特殊狀態的選擇。

 

一.簡單選擇器

在使用 jQuery 選擇器時,我們首先必須使用“$()”函數來包裝我們的 CSS 規則。而CSS 規則作為參數傳遞到 jQuery 對象內部后,再返回包含頁面中對應元素的 jQuery 對象。隨后,我們就可以對這個獲取到的 DOM 節點進行行為操作了。

#box {                        //使用 ID 選擇器的 CSS 規則

  color:red;           //將 ID 為 box 的元素字體顏色變紅

}

在 jQuery 選擇器里,我們使用如下的方式獲取同樣的結果:

$('#box').css('color', 'red');               //獲取 DOM 節點對象,並添加行為

 

那么除了 ID 選擇器之外,還有兩種基本的選擇器,分別為:元素標簽名和類(class):

 

圖1

 

$('div').css('color', 'red');                  //元素選擇器,返回多個元素

$('#box').css('color', 'red');               //ID 選擇器,返回單個元素

$('.box').css('color', 'red');                //類(class)選擇器,返回多個元素

為了證明 ID 返回的是單個元素,而元素標簽名和類(class)返回的是多個,我們可以采用 jQuery 核心自帶的一個屬性 length 或 size()方法來查看返回的元素個數。

alert($('div').size());                   //3 個

alert($('#box').size());               //1 個,后面兩個失明了(只識別找到的第一個)

alert($('.box').size());                 //3 個

同理,你也可以直接使用 jQuery 核心屬性來操作:

alert($('#box').length);            //1 個,后面失明了

 

警告:有個問題特別要注意,ID 在頁面只允許出現一次,我們一般都是要求開發者要遵守和保持這個規則。但如果你在頁面中出現三次,並且在 CSS 使用樣式,那么這三個元素還會執行效果。但如果,你想在 jQuery 這么去做,那么就會遇到失明的問題。所以,開發者必須養成良好的遵守習慣,在一個頁面僅使用一個 ID。

$('#box').css('color', 'red');               //只有第一個 ID 變紅,后面兩個失明

 

jQuery 選擇器的寫法與 CSS 選擇器十分類似,只不過他們的功能不同。CSS 找到元素后添加的是單一的樣式,而 jQuery 則添加的是動作行為。最重要的一點是:CSS 在添加樣式的時候,高級選擇器會對部分瀏覽器不兼容,而 jQuery 選擇器在添加 CSS 樣式的時候卻不必為此煩惱。

#box > p {                           //CSS 子選擇器,IE6 不支持

  color:red;

}

$('#box > p').css('color','red');                    //jQuery 子選擇器,兼容了 IE6

jQuery 選擇器支持 CSS1、CSS2 的全部規則,支持 CSS3 部分實用的規則,同時它還有少量獨有的規則。所以,對於已經掌握 CSS 的開發人員,學習 jQuery 選擇器幾乎是零成本。

而jQuery選擇器在獲取節點對象的時候不但簡單, 還內置了容錯功能, 這樣避免像JavaScript那樣每次對節點的獲取需要進行有效判斷。

$('#pox').css('color', 'red');                //不存在 ID 為 pox 的元素,也不報錯

document.getElementById('pox').style.color = 'red';               //報錯了(so參考《精通JS》)

因為 jQuery 內部進行了判斷,而原生的 DOM 節點獲取方法並沒有進行判斷,所以導致了一個錯誤,原生方法可以這么判斷解決這個問題:

1 if (document.getElementById('pox')) {            //先判斷是否存在這個對象(參考《精通JS》)
2 
3   document.getElementById('pox').style.color = 'red';
4 
5 }

 

那么對於缺失不存在的元素,我們使用 jQuery 調用的話,怎么去判斷是否存在呢?因為本身返回的是 jQuery 對象,可能會導致不存在元素存在與否,都會返回 true。

1 if ($('#pox').length > 0) {                    //判斷元素包含數量即可
2 
3   $('#pox').css('color', 'red');
4 
5 }

 

除了這種方式之外,還可以用轉換為 DOM 對象的方式來判斷,例如:

if ($('#pox').get(0)) {} 或 if ($('#pox')[0]) {}   //通過數組下標也可以獲取 DOM 對象

 

二.進階選擇器

在簡單選擇器中,我們了解了最基本的三種選擇器:元素標簽名、ID 和類(class)。那么在基礎選擇器外,還有一些進階和高級的選擇器方便我們更精准的選擇元素。

 

圖2

 

//群組選擇器

span, em, .box {               //多種選擇器添加紅色字體

  color:red;

}

$('span, em, .box').css('color', 'red');                //群組選擇器 jQuery 方式

 

//后代選擇器

ul li a {                //層層追溯到的元素添加紅色字體

  color:red;

}

$('ul li a').css('color', 'red');              //群組選擇器 jQuery 方式

 

//通配選擇器

* {             //頁面所有元素都添加紅色字體

  color:red;

}

$('*').css('color', 'red');            //通配選擇器

目前介紹的六種選擇器,在實際應用中,我們可以靈活的搭配,使得選擇器更加的精准和快速:

$('#box p, ul li *').css('color', 'red');                  //組合了多種選擇器

警告:在實際使用上,通配選擇器一般用的並不多,尤其是在大通配上,比如:$('*'),這種使用方法效率很低,影響性能,建議竟可能少用。

還有一種選擇器,可以在 ID 和類(class)中指明元素前綴,比如:

$('div.box');                  //限定必須是.box 元素獲取必須是 div

$('p#box div.side');           //同上

類(class)有一個特殊的模式, 就是同一個 DOM 節點可以聲明多個類(class)。 那么對於這種格式,我們有多 class 選擇器可以使用,但要注意和 class 群組選擇器的區別。

.box.pox {                   //雙 class 選擇器,IE6 出現異常

  color:red;

}

$('.box.pox').css('color', 'red');                 //兼容 IE6,解決了異常

多 class 選擇器是必須一個 DOM 節點同時有多個 class,用這多個 class 進行精確限定。而群組 class 選擇器,只不過是多個 class 進行選擇而已。

$('.box, .pox').css('color', 'red');                //加了逗號,體會區別

 

警告:在構造選擇器時,有一個通用的優化原則:只追求必要的確定性。當選擇器篩選越復雜,jQuery 內部的選擇器引擎處理字符串的時間就越長。比如:

$('div#box ul li a#link');              //讓 jQuery 內部處理了不必要的字符串

$('#link');                   //ID 是唯一性的,准確度不變,性能提升

 

三.高級選擇器

在前面我們介紹了六種最常規的選擇器, 一般來說通過這六種選擇器基本上可以解決所有DOM 節點對象選擇的問題。但在很多特殊的元素上,比如父子關系的元素,兄弟關系的元素,特殊屬性的元素等等。在早期 CSS 的使用上,由於 IE6 等低版本瀏覽器不支持,所以這些高級選擇器的使用也不具備普遍性,但隨着 jQuery 兼容,這些選擇器的使用頻率也越來越高。

 

圖3

 

在層次選擇器中, CSS模式除了后代選擇器之外, 其他三種高級選擇器是不支持 IE6 的, 而 jQuery卻是兼容 IE6 的。

 

//后代選擇器

$('#box p').css('color', 'red');           //全兼容

jQuery 為后代選擇器提供了一個等價 find()方法

$('#box').find('p').css('color', 'red');                  //和后代選擇器等價

 

//子選擇器,孫子后失明

#box > p {                  //IE6 不支持

  color:red;

}

$('#box > p').css('color', 'red');                   //兼容 IE6

jQuery 為子選擇器提供了一個等價 children()方法

$('#box').children('p').css('color', 'red');                   //和子選擇器等價

 

//next 選擇器(下一個同級節點)

#box + p {                  //IE6 不支持

  color:red;

}

$('#box+p').css('color', 'red');           //兼容 IE6

jQuery 為 next 選擇器提供了一個等價的方法 next()

$('#box').next('p').css('color', 'red');                  //和 next 選擇器等價

 

//nextAll 選擇器(后面所有同級節點)

#box ~ p {                  //IE6 不支持

  color:red;

}

$('#box ~ p').css('color', 'red');                 //兼容 IE6

jQuery 為 nextAll 選擇器提供了一個等價的方法 nextAll()

$('#box').nextAll('p').css('color', 'red');             //和 nextAll 選擇器等價

 

層次選擇器對節點的層次都是有要求的,比如子選擇器,只有子節點才可以被選擇到,孫子節點和重孫子節點都無法選擇到。next 和 nextAll 選擇器,必須是同一個層次的后一個和后 N 個,不在同一個層次就無法選取到了。

注意:在 find()、next()、nextAll()和 children()這四個方法中,如果不傳遞參數,就相當於傳遞了“*” ,即任何節點,我們不建議這么做,不但影響性能,而且由於精准度不佳可能在復雜的 HTML 結構時產生怪異的結果。

$('#box').next();                 //相當於$('#box').next('*');

 

為了補充高級選擇器的這三種模式,jQuery 還提供了更加豐富的方法來選擇元素:

$('#box').prev('p').css('color', 'red');                  //同級上一個元素

$('#box').prevAll('p').css('color', 'red');            //同級所有上面的元素

nextUntil()和 prevUnitl()方法是選定同級的下面或上面的所有節點,選定非指定的所有元素,一旦遇到指定的元素就停止選定。

$('#box').prevUntil('p').css('color', 'red');        //同級上非指定元素選定,遇到則停止

$('#box').nextUntil('p').css('color', 'red');        //同級下非指定元素選定,遇到則停止

siblings()方法正好集成了 prevAll()和 nextAll()兩個功能的效果,及上下相鄰的所有元素進行選定:

$('#box').siblings('p').css('color', 'red');            //同級上下所有元素選定

//等價於下面:

$('#box').prevAll('p').css('color', 'red');            //同級上所有元素選定

$('#box').nextAll('p').css('color', 'red');            //同級下所有元素選定

警告:切不可寫成“$('#box').prevAll('p').nextAll('p').css('color', 'red');”這種形式,因為prevAll('p')返回的已經是上方所有指定元素,然后再 nextAll('p')選定下方所有指定元素,這樣必然出現錯誤。

理論上來講,jQuery 提供的方法 find()、next()、nextAll()和 children()運行速度要快於使用高級選擇器。 因為他們實現的算法有所不同, 高級選擇器是通過解析字符串來獲取節點對象,而 jQuery 提供的方法一般都是單個選擇器,是可以直接獲取的。但這種快慢的差異,對於客戶端腳本來說沒有太大的實用性, 並且速度的差異還要取決了瀏覽器和選擇的元素內容。比如,在 IE6/7 不支持 querySelectorAll()方法,則會使用“Sizzle”引擎,速度就會慢,而其他瀏覽器則會很快。有興趣的可以了解這個方法和這個引擎。

 

選擇器快慢分析:

//這條最快,會使用原生的 getElementById、ByName、ByTagName 和 querySelectorAll()

$('#box').find('p');

 

//jQuery 會自動把這條語句轉成$('#box').find('p'),這會導致一定的性能損失。它比最快的形式慢了 5%-10%

$('p', '#box');

 

//這條語句在 jQuery 內部,會使用$.sibling()和 javascript 的 nextSibling()方法,一個個遍歷節點。它比最快的形式大約慢 50%

$('#box').children('p');

 

//jQuery 內部使用 Sizzle 引擎,處理各種選擇器。Sizzle 引擎的選擇順序是從右到左,所以這條語句是先選 p,然后再一個個過濾出父元素#box,這導致它比最快的形式大約慢70%

$('#box > p');

 

//這條語句與上一條是同樣的情況。但是,上一條只選擇直接的子元素,這一條可以用於選擇多級子元素,所以它的速度更慢,大概比最快的形式慢了 77%。

$('#box p');

 

//jQuery 內部會將這條語句轉成$('#box').find('p'),比最快的形式慢了 23%。

$('p', $('#parent'));

綜上所屬,最快的是 find()方法,最慢的是$('#box p')這種高級選擇器。如果一開始將$('#box')進行賦值,那么 jQuery 就對其變量進行緩存,那么速度會進一步提高。

var box = $('#box');

var p = box.find('p');

 

注意:我們應該推薦使用哪種方案呢?其實,使用哪種都差不多。這里,我們推薦使用jQuery 提供的方法。 因為不但方法的速度比高級選擇器運行的更快, 並且它的靈活性和擴展性要高於高級選擇器。使用“+”或“~”從字面上沒有 next 和 nextAll 更加語義化,更加清晰,jQuery 的方法更加豐富,提供了相對的 prev 和 prevAll。畢竟 jQuery 是編程語言,需要能夠靈活的拆分和組合選擇器,而使用 CSS 模式過於死板。所以,如果 jQuery 提供了獨立的方法來代替某些選擇器的功能,我們還是推薦優先使用獨立的方法。

 

屬性選擇器

 

圖4

 

屬性選擇器也不支持 IE6, 所以在 CSS 界如果要兼容低版本, 那么也是非主流。 但 jQuery卻不必考慮這個問題。

 

Thank you ,Mr.Lee!

For my Lover, CC!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM