jQuery里有一个概念,你几乎每写一行代码都会碰到,那就是选择器。它的作用一句话就能说明白——帮你在HTML文档里找到想操作的那个或那组元素。没找到元素,后续的样式修改、事件绑定、动画效果就无从谈起。所以把选择器弄熟,是用好这个库的基础。
$() 工厂函数:所有选择的起点
每一个jQuery选择器都以美元符号加一对圆括号开头,也就是$()。这个结构有个正式名称,叫工厂函数。它的工作是接收你传入的选择器表达式,然后在DOM树里匹配出对应的元素,包装成jQuery对象返给你。
如果你项目中同时用了别的库也占用$这个符号,jQuery提供了退路——用jQuery()代替$(),功能一样,只是写法长一点。这种情况现在不常见,但维护很老的系统时可能会遇到,心里有个数就行。
工厂函数的三个基本构件
jQuery选择器在选取元素时,主要依赖三种基础形式,其他复杂选择器都是它们的组合或变体。
-
标签名选择:直接写HTML标签的名字。比如
$('p')会把页面上所有的<p>段落都选中。 -
ID选择:使用
#号加ID值。比如$('#real-id')只选中页面上那一个id为real-id的元素。ID在页面里理论上是唯一的,所以这个选择器返回的通常就是单个元素。 -
类选择:使用
.号加类名。比如$('.real-class')会选中所有拥有class="real-class"的元素,可能是一个,也可能是一组。
下面是一个最简单的标签选择器示例,给所有段落统一加上背景色。文件命名为tag-selector.html:
<!DOCTYPE html>
<html>
<head>
<title>标签选择器示例</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script>
$(document).ready(function() {
$("p").css("background-color", "pink");
});
</script>
</head>
<body>
<p>这是第一个段落。</p>
<p>这是第二个段落。</p>
<p>这是第三个段落。</p>
</body>
</html>
页面跑起来后,三个段落的背景都会变成粉色。你看到的效果是统一生效,背后jQuery做了一遍隐式迭代——你不需要写循环,它自动帮你把每个匹配的<p>都应用了样式。
基础选择器一览
这几个是日常用得频繁的类型,掌握它们就能覆盖大部分简单场景。
| 选择器 | 写法示例 | 说明 |
|---|---|---|
| 元素名 | $("p") |
匹配所有该标签的元素。 |
| #ID | $("#firstname") |
匹配id为firstname的唯一元素。 |
| .类名 | $(".primary") |
匹配所有class含primary的元素。 |
| 多类选择 | $(".primary,.secondary") |
匹配class含primary或secondary的元素。 |
| 多元素选择 | $("h1,div,p") |
同时匹配多种标签,结果合并在一起。 |
| 通配符 * | $("*") |
匹配DOM中的每一个元素。 |
我个人习惯是,能用ID定位就用ID,它走得快,代码可读性也强。类选择器适合批量的样式或行为绑定。但不太建议滥用通配符*,尤其是在结构深的页面里,性能消耗比精准选择器高出一截。
按元素在DOM中的位置筛选
有时候我们不是要全部某个类型的元素,而是“第一个段落”或“表格里偶数行”。这类需求用位置过滤器很方便。
| 选择器 | 写法示例 | 说明 |
|---|---|---|
| :first | $("p:first") |
匹配第一个<p>。 |
| :last | $("p:last") |
匹配之后一个<p>。 |
| :even | $("tr:even") |
匹配索引为偶数的<tr>,索引从0开始。 |
| :odd | $("tr:odd") |
匹配索引为奇数的<tr>。 |
| :eq(index) | $("ul li:eq(3)") |
匹配索引等于3的<li>(即第四个)。 |
| :gt(no) | $("ul li:gt(3)") |
匹配索引大于3的<li>。 |
| :lt(no) | $("ul li:lt(3)") |
匹配索引小于3的<li>。 |
这里注意:even和:odd是从索引0开始算,跟日常数数“第一、第二”对不上。我第一次用就给表格加了斑马纹,结果发现颜色反了,排查才意识到是这个问题,印象一直很深。如果你要的是直觉上的奇数偶数行,CSS3的nth-child伪类更符合人的思维,两者别搞混。
本节课程知识要点::even基于JavaScript的0基索引,表格第一行索引为0属于偶数;需要按人类习惯的奇偶行做样式区分时,建议用CSS原生的:nth-child(odd)和:nth-child(even)。
层级关系选择器
页面元素不是孤立的,它们有父子、兄弟关系。jQuery提供了多种方式来表达这些层级关系。
| 选择器 | 写法示例 | 说明 |
|---|---|---|
| parent > child | $("div > p") |
匹配<div>的直接子元素<p>,隔代不选。 |
| parent descendant | $("div p") |
匹配<div>内部所有<p>,不管嵌套多深。 |
| element + next | $("div + p") |
匹配紧跟在<div>后面的那个<p>兄弟。 |
| element ~ siblings | $("div ~ p") |
匹配<div>后面所有同级的<p>兄弟。 |
我写代码号调试时,经常会先用>收紧匹配范围,避免后代选择器的范围过大,导致样式不小心污染到深层嵌套。尤其在组件嵌套复杂的页面里,div p可能影响很深,div > p则严格限制在直接子级上。
表单相关的选择器
jQuery为表单元素专门设计了一套选择器,在编写交互逻辑时很常用。
| 选择器 | 写法示例 | 说明 |
|---|---|---|
| :input | $(":input") |
匹配所有<input>、<textarea>、<select>、<button>。 |
| :text | $(":text") |
匹配type为text的<input>。 |
| :password | $(":password") |
匹配密码框。 |
| :radio | $(":radio") |
匹配所有单选按钮。 |
| :checkbox | $(":checkbox") |
匹配所有复选框。 |
| :submit | $(":submit") |
匹配提交按钮。 |
| :checked | $(":checked") |
匹配已勾选的复选框或单选按钮。 |
| :selected | $(":selected") |
匹配<select>中当前被选中的<option>。 |
| :enabled / :disabled | $(":enabled") / $(":disabled") |
匹配启用或禁用的表单元素。 |
举个例子,获取用户已勾选的复选框可以用一行代码:
var checkedBoxes = $("input:checkbox:checked");
这个写法是我做表单验证时常用的,简洁且意图明确,不用写循环判断checked属性。
属性选择器
当元素没有明显的ID或类名时,按属性筛选是一个很好的补充手段。
| 选择器 | 写法示例 | 说明 |
|---|---|---|
| [attribute] | $("[href]") |
匹配所有带href属性的元素。 |
| [attr=value] | $("[href='default.htm']") |
属性值等于指定字符串。 |
| [attr!=value] | $("[href!='default.htm']") |
属性值不等于指定字符串。 |
| [attr^=value] | $("[title^='Tom']") |
属性值以指定字符串开头。 |
| [attr$=value] | $("[href$='.jpg']") |
属性值以指定字符串结尾。 |
| [attr*=value] | $("[title*='hello']") |
属性值包含指定字符串。 |
这套选择器在操作链接和图片时很实用。比如给所有指向外部PDF文件的链接加上特殊标记:
$("a[href$='.pdf']").css("color", "#c62828");
代码号里,[href$='.pdf']精确抓到所有以.pdf结尾的链接,后续想改样式还是加图标都很方便。
内容与可见性相关的选择器
| 选择器 | 写法示例 | 说明 |
|---|---|---|
| :contains(text) | $(":contains('Hello')") |
匹配内部文本包含"Hello"的元素。 |
| :has(selector) | $("div:has(p)") |
匹配内部包含<p>的<div>。 |
| :empty | $(":empty") |
匹配没有子元素也没有文本的标签。 |
| :parent | $(":parent") |
匹配有子元素或文本的非空元素。 |
| :hidden | $("p:hidden") |
匹配处于隐藏状态的<p>。 |
| :visible | $("table:visible") |
匹配正在显示的<table>。 |
:hidden和:visible在需要根据元素显示状态做条件判断时特别顺手。比如检查一个错误提示区域当前是否可见,再决定要不要显示它。
$符号冲突处理
前面提过,如果你的页面同时加载了另一个用$做全局函数的库,jQuery的选择器语法可能会失灵。解决方案是用jQuery.noConflict()释放$,之后改用完整的jQuery()来写代码:
jQuery.noConflict();
jQuery(function() {
jQuery("p").css("color", "#1565c0");
});
多打几个字,但换来的是一份稳定的环境。我维护过的老项目里,同一个页面同时加载jQuery和Prototype的情况虽然不多见,一旦碰上,理解noConflict机制就能快速把问题解决。
选择器分类速查挂在这儿备查即可,实际用到时再回来翻。我的经验是,先扎实掌握标签、ID、类、层级、几个关键的位置过滤器和表单选择器,这七八种基本覆盖了大部分日常业务的定位需求。后续的复杂组合,本质上都是这些基础构件的叠加。
有什么具体场景需要上手调试,或者想探讨某个选择器的性能细节,随时可以给 alan@ebingou.cn 来信交流。