第3章常規選擇器

第 3 章 常規選擇器

學習要點:
1.簡單選擇器
2.進階選擇器
3.高級選擇器

jQuery 最核心的組成部分就是:選擇器引擎。它繼承了 CSS 的語法,可以對 DOM 元
素的標簽名、屬性名、狀態等進行快速準確的選擇,并且不必擔心瀏覽器的兼容性。jQuery
選擇器實現了 CSS1~CSS3 的大部分規則之外,還實現了一些自定義的選擇器,用于各種
特殊狀態的選擇。備注:課程必須有(X)html+CSS 基礎。

一. 簡單選擇器

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

#box { //使用 ID 選擇器的 CSS 規則
color:red; //將 ID 為 box 的元素字體顏色變紅
}

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

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

那么除了 ID 選擇器之外,還有兩種基本的選擇器,分別為:元素標簽名和類(class):
選擇器 CSS 模式 jQuery 模式 描述
元素名 div {} $('div') 獲取所有 div 元素的 DOM 對象

ID #box {} $('#box') 獲取一個 ID 為 box 元素的 DOM 對象
類(class) .box{} $('.box') 獲取所有class為box的所有DOM對象
$('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'; //報錯了
```
因為 jQuery 內部進行了判斷,而原生的 DOM 節點獲取方法并沒有進行判斷,所以導
致了一個錯誤,原生方法可以這么判斷解決這個問題:
```
if (document.getElementById('pox')) { //先判斷是否存在這個對象
document.getElementById('pox').style.color = 'red';
}
```
那么對于缺失不存在的元素,我們使用 jQuery 調用的話,怎么去判斷是否存在呢?因
為本身返回的是 jQuery 對象,可能會導致不存在元素存在與否,都會返回 true。
```
if ($('#pox').length > 0) { //判斷元素包含數量即可
$('#pox').css('color', 'red');
}
```
除了這種方式之外,還可以用轉換為 DOM 對象的方式來判斷,例如:
if ($('#pox').get(0)) {} 或 if ($('#pox')[0]) {} //通過數組下標也可以獲取 DOM 對象

###  二. 進階選擇器

在簡單選擇器中,我們了解了最基本的三種選擇器:元素標簽名、ID 和類(class)。那么
在基礎選擇器外,還有一些進階和高級的選擇器方便我們更精準的選擇元素。
選擇器 CSS 模式 jQuery 模式 描述
群組選擇器 span,em,.box {} $('span,em,.box') 獲取多個選擇器的 DOM 對象
后代選擇器 ul li a {} $('ul li a') 獲取追溯到的多個 DOM 對象
通配選擇器 * {} $('*') 獲取所有元素標簽的 DOM 對象
//群組選擇器
```
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 兼容,這些選擇器的使用頻率也越
來越高。
層次選擇器
在層次選擇器中,除了后代選擇器之外,其他三種高級選擇器是不支持 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'); //和子選擇器等價
```
選擇器 CSS 模式 jQuery 模式 描述
后代選擇器 ul li a {} $('ul li a') 獲取追溯到的多個 DOM 對象
子選擇器 div > p {} $('div p') 只獲取子類節點的多個 DOM 對象
next 選擇器 div + p {} $('div + p') 只獲取某節點后一個同級DOM對象
nextAll 選擇器 div ~ p {} $('div ~ p') 獲取某節點后面所有同級DOM對象
//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 提供了獨立
的方法來代替某些選擇器的功能,我們還是推薦優先使用獨立的方法。
屬性選擇器

CSS 模式 jQuery 模式 描述

a[title] $('a[title]') 獲取具有這個屬性的 DOM 對象
a[title=num1] $('a[title=num1]')

獲取具有這個屬性=這個屬性值的DOM對
象
a[title^=num] $('a[title^=num]')

獲取具有這個屬性且開頭屬性值匹配的

DOM 對象
a[title|=num] $('a[title|=num]')

獲取具有這個屬性且等于屬性值或開頭屬
性值匹配后面跟一個“-”號的 DOM 對象

a[title$=num] $('a[title$=num]')

獲取具有這個屬性且結尾屬性值匹配的
DOM 對象

a[title!=num] $('a[title!=num]')

獲取具有這個屬性且不等于屬性值的
DOM 對象
a[title~=num] $('a[title~=num]')

獲取具有這個屬性且屬性值是以一個空格
分割的列表,其中包含屬性值的 DOM 對
象
a[title*=num] $('a[title*=num]')

獲取具有這個屬性且屬性值含有一個指定
字串的 DOM 對象

a[bbb][title=num1] $('a[bbb][title=num1]')

獲取具有這個屬性且屬性值匹配的 DOM
對象
屬性選擇器也不支持 IE6,所以在 CSS 界如果要兼容低版本,那么也是非主流。但 jQuery
卻不必考慮這個問題。
//選定這個屬性的
```
a[title] { //IE6 不支持
color:red;
}

$('a[title]').css('color', 'red'); //兼容 IE6 了

//選定具有這個屬性=這個屬性值的

a[title=num1] { //IE6 不支持
color:red;
}
$('a[title=num1]').css('color', 'red'); //兼容 IE6 了

//選定具有這個屬性且開頭屬性值匹配的
a[title^=num] { //IE6 不支持
color:red;
}
$('a[title=^num]').css('color', 'red'); //兼容 IE6 了
//選定具有這個屬性且等于屬性值或開頭屬性值匹配后面跟一個“-”號
a[title|=num] { //IE6 不支持
color:red;
}
$('a[title|="num"]').css('color', 'red'); //兼容 IE6 了
//選定具有這個屬性且結尾屬性值匹配的
a[title$=num] { //IE6 不支持
color:red;
}
$('a[title$=num]').css('color','red'); //兼容 IE6 了
//選定具有這個屬性且屬性值不想等的
a[title!=num1] { //不支持此 CSS 選擇器
color:red;
}
$('a[title!=num1]').css('color','red'); //jQuery 支持這種寫法
//選定具有這個屬性且屬性值是以一個空格分割的列表,其中包含屬性值的
a[title~=num] { //IE6 不支持
color:red;
}
$('a[title~=num1]').css('color','red'); //兼容 IE6
//選定具有這個屬性且屬性值含有一個指定字串的
a[title*=num] { //IE6 不支持
color:red;
}
$('a[title*=num]').css('color','red'); //兼容 IE6
//選定具有多個屬性且屬性值匹配成功的
a[bbb][title=num1] { //IE6 不支持
color:red;
}
$('a[bbb][title=num1]').css('color','red'); //兼容 IE6
```
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標簽默認的外補...
    _Yfling閱讀 13,796評論 1 92
  • 一、樣式篇 第1章 初識jQuery (1)環境搭建 進入官方網站獲取最新的版本 http://jquery.co...
    凜0_0閱讀 3,451評論 0 44
  • 通過jQuery,您可以選取(查詢,query)HTML元素,并對它們執行“操作”(actions)。 jQuer...
    枇杷樹8824閱讀 670評論 0 3
  • 你說我是超人? 不,我只是一枚帶娃奔跑的設計師。 1. 近日,好幾個小伙伴見了我都感嘆:嘿,親愛的,你是超人嗎?懷...
    得樂閱讀 302評論 4 6
  • 相關設置可以去http://www.ctan.org/搜索對應的包的用法和設置 一些無關緊要的定義 可以看到xec...
    hopless閱讀 1,662評論 0 4