2.5 自定义选择符

2.5 自定义选择符

除了各种CSS选择符之外,jQuery还添加了独有的完全不同的自定义选择符。这些自定义选择符进一步增强了已经十分强大的CSS选择符,为我们提供了在页面上选择元素的新手段。
性能提示
只要可能,jQuery就会使用浏览器原生的DOM选择符引擎去查找元素。但在使用自定义选择符的时候,就无法使用速度最快的原生方法了。因此,建议读者在能够使用原生方法的情况下,就不要频繁地使用自定义选择符,以确保性能。
jQuery中的多数自定义选择符都可以让我们从已经找到的元素中选出一或多个元素。
自定义选择符通常跟在一个CSS选择符后面,基于已经选择的元素集的位置来查找元素。自定义选择符的语法与CSS中的伪类选择符语法相同,即选择符以冒号(:)开头。例如,我们想要从带有horizontal类的<div>集合中选择第2项,那么应该使用下面的代码:

1
$('div.horizontal:eq(1)') 

注意,因为JavaScript数组采用从0开始的编号方式, 所以eq(1)取得的是集合中的第2个元素。而CSS则是从1开始的,因此CSS选择符$(div:nth-child(1)')取得的是作为其父元素第1个子元素的所有div元素。如果记不清哪个从0开始,哪个从1开始,可以参考jQuery API文档

2.5.1 每隔一行为表格添加样式

jQuery库中的两个十分有用的自定义选择符是:odd和:even。下面,我们就来看一看如何通过这两个选择符为表格添加基本的条纹样式,针对下面的表格:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<h2>Shakespeare's Plays</h2>
<table>
<tr>
<td>As You Like It</td>
<td>Comedy</td>
<td></td>
</tr>
<tr>
<td>All's Well that Ends Well</td>
<td>Comedy</td>
<td>1601</td>
</tr>
<tr>
<td>Hamlet</td>
<td>Tragedy</td>
<td>1604</td>
</tr>
<tr>
<td>Macbeth</td>
<td>Tragedy</td>
<td>1606</td>
</tr>
<tr>
<td>Romeo and Juliet</td>
<td>Tragedy</td>
<td>1595</td>
</tr>
<tr>
<td>Henry IV, Part I</td>
<td>History</td>
<td>1596</td>
</tr>
<tr>
<td>Henry V</td>
<td>History</td>
<td>1599</td>
</tr>
</table>
<h2>Shakespeare's Sonnets</h2>
<table>
<tr>
<td>The Fair Youth</td>
<td>1–126</td>
</tr>
<tr>
<td>The Dark Lady</td>
<td>127–152</td>
</tr>
<tr>
<td>The Rival Poet</td>
<td>78–86</td>
</tr>
</table>

在样式表中添加一点样式,表格的表头和单元格就清晰了许多。现在,这个表格有白色的背景,但行与行之间没有区别,如图2-8所示。

可以在样式表中为所有表格行添加一种样式,然后再为奇数行定义一个alt类。

1
2
3
4
5
6
tr { 
background-color: #fff;
}
.alt {
background-color: #ccc;
}

最后编写jQuery代码,将这个类添加到表格中的奇数行(<tr>标签),如代码清单2-6所示。

1
2
3
$(document).ready(function() { 
$('tr:even').addClass('alt');
});

等一等!为什么针对奇数行使用:even选择符呢?很简单,:eq()选择符、:odd:even选择符都使用JavaScript内置从0开始的编号方式,因此,第一行的编号为0(偶数),第二行的编号为1(奇数) ,依此类推。知道这一点之后,我们希望上面那几行代码能够生成如图2-9所示的结果。
图2-9

不过,要注意的是,如果一个页面上存在另外一个表格,我们则真有可能会看到意料之外的结果。例如,因为Plays表格中的最后一行为”另一种”浅灰色背景,所以Sonnets表格的第一行的背景就会为白色。解决这个问题的一种方法是使用:nth-child()选择符。这个选择符相对于元素的父元素而非当前选择的所有元素来计算位置,它可以接受数值、oddeven作为参数,如代码清单2-7所示。

1
2
3
$(document).ready(function() { 
$('tr:nth-child(odd)').addClass('alt');
});

值得一提的是,:nth-child()jQuery中唯一从1开始计数的选择符。要实现与图2-8所示相同的条纹交替效果,并且确保同一文档中的多个表格的效果一致,需要使用odd而不是even参数。替换了参数之后,两个表格出现了一致的条纹交替效果,如图2-10所示。

2.5.2 基于上下文内容选择元素

下面,我们介绍最后一个自定义选择符。假设出于某种原因,我们希望突出显示提到任何一种Henry游戏的所有表格单元。为此,我们所要做的就是在样式表中添加一个声明了粗体和斜体文本的类:

1
2
3
4
.highlight{
font-weight:bold;
font-style:italic;
}

然后向jQuery代码中添加一行代码,其中使用的是:contains()选择符,参见代码清单2-8。

1
2
3
4
$(document).ready(function() { 
$('tr:nth-child(odd)').addClass('alt');
$('td:contains(Henry)').addClass('highlight');
});

这样,在可爱的条纹表格中,就能够看到突出显示的Henry游戏了,如图2-11所示。

必须注意,:contains()选择符区分大小写。换句话说,使用不带大写”H”的$('td:contains(henry)'),不会选择任何单元格。
诚然,不使用jQuery(或任何客户端编程语言)也可以通过其他方式实现这种行条纹和突出显示效果。然而,在内容由程序动态生成,而我们又无权改动HTML和服务器端代码的情况下,jQuery加上CSS对这种样式化操作提供了优秀的替换方案。

2.5.3 基于表单的选择符

自定义选择符并不局限于基于元素的位置选择元素。比如,在操作表单时,jQuery的自定义选择符以及后来补充的CSS3选择符同样可以简化选择元素的任务。表2-2列出了其中一些适用于表单的选择符。

表2-2 表单选择符
选择符 匹配
:input 输入字段、文本区、选择列表和按钮元素
:button 按钮元素或type属性值为button的输入元素
:enabled 启用的表单元素
:disabled 禁用的表单元素
:checked 勾选的单选按钮或复选框
:selected 选择的选项元素

与其他选择符类似,组合使用表单选择符可以更有针对性。例如,使用$('input[type="radio"]:checked')可以选择所有选中的单选按钮(而不是复选框) ,而使用$('input[type="password"],input[type="text"]:disabled')则可以选择所有密码输入字段和禁用的文本输入字段。可见,即便是使用自定义选择符,也可以按照基本的CSS语法来定义匹配的元素列表。