一柄轻剑能伤敌,靠的是认得清敌我。选中一个元素之后,还得会看它的出身、父母、兄弟—— 这些“亲戚关系”,就是遍历。这一式,我们学会在元素家族里认亲。
- 用
parent/children/find/siblings/next/prev/closest在家族里认亲 - 理解
closest与事件委托的黄金配合 - 会用
each()逐个处理选中的元素 - 会用
filter/first/last/eq缩小包围圈 - 会用
not/is/has与Until系列做更聪明的问询
元素的家族关系
把页面看成一张家谱——每个标签都是某个标签的子嗣。按钮小友的一家,长这样:
document
└── html
├── head
└── body
├── header
└── main
├── h2(标题)
├── .card(第一张)── siblings:互为兄弟
│ └── button(点我)← 你在这里
├── .card(第二张)── next() / prev():同级的前后邻居
└── p(段落)
围绕这张家谱,jQuery 准备了一组“认亲”方法:
| 方法 | 家族说法 | 找谁 |
|---|---|---|
parent() | 找父亲 | 上一级父元素,只找一层 |
parents() | 列祖列宗 | 所有祖先;可传选择器过滤,如 parents('.page') |
children() | 亲儿子 | 直接子元素;可传选择器过滤 |
find() | 满门子孙 | 所有后代;必须传选择器,如 find('a') |
siblings() | 兄弟姐妹 | 同级全部;可传选择器过滤 |
next() / prev() | 紧邻的弟与兄 | 后一个 / 前一个同级元素,各只找一个 |
closest() | 一路向上寻亲 | 从自己开始向上,找最近的匹配;必须传选择器,可能命中自己 |
向上找:parent / parents / closest
parent() 只找上一级;parents() 把一路向上的祖先全部找来(可传选择器过滤);
closest(选择器) 从自己开始向上,返回最近的一个匹配。
最后一个正是事件委托的黄金搭档——事件绑在父级上,处理时却要操作“所在的那张卡片”,一记 closest 就位。
内功卡
吐纳打坐,贵在坚持。
轻功卡
每日一纵,身轻如燕。
剑法卡
剑走轻灵,意在剑先。
按钮在 .card-body 里,卡片在两层之上——不管隔几层,
closest('.card') 都能一步找到“最近的卡片”,三张卡各管各的。
向下找:children / find
往下走的两个方法分工明确:children() 只认亲儿子(直接子元素),
find() 认满门子孙(所有后代,必须传选择器)。拿例 1 的卡片阵试刀:
三张卡都住在 .col 列里面,所以对 #jq07-deck 来说它们不是“儿子”而是“孙子”——
children 扑空,find 全中。想找哪层,先想清楚辈分。
兄弟姐妹:siblings / next / prev
同级之间也有讲究:siblings() 把兄弟姐妹一网打尽(可传选择器过滤),
next() / prev() 只找紧挨着的后一个 / 前一个。
逐个点名:each()
jQuery 对选中集合的隐式遍历是“一声令下,全员行动”。可有些活儿必须逐个点名——
比如“隔一行染一色”,得知道每个元素排第几。这时请 each() 出场:
| 招式 | 境界 | 口诀 |
|---|---|---|
| 选择器 | 入门 | 找到即命中 |
| 事件 | 入门 | 点谁谁回应 |
| 动画 | 进阶 | 动静皆有度 |
| 遍历 | 进阶 | 认亲不迷路 |
index % 2 === 1 挑出第 2、4 行(序号从 0 数,奇数序号正是视觉上的偶数行)。
顺带一提::even / :odd 这类位置伪类在 jQuery 4 里依然能用,
但官方更推荐用 each 或 filter 这种“看得见逻辑”的写法——
判断条件白纸黑字写在那儿,两年后回看也知道自己当时在想什么。
- 选择器
- 内容与属性
- 类与样式
- 事件
点上面的按钮,看结果。
这就是 each 的日常:一边走一边收集,走完再统一收尾。
记一笔——each 走完后会把原来的集合原样还回来,链式调用不受影响。
缩小包围圈:filter / first / last / eq
选中一堆元素后,还可以从中再挑:first() 取第一个、last() 取最后一个、
eq(2) 取序号为 2 的那一个(即第三个,从 0 数)、filter() 按选择器或函数筛选。
第一式就见过它:$('p').css('color', 'red') 会让所有段落变红。
隐式遍历是 jQuery 的默认性格——“对选中的每个元素都动手”;而本式的遍历方法负责“换个圈子再动手”。
位置伪类 :first / :last 在 jQuery 4 里仍然可用,但方法版
.first() / .last() 更清晰、也更快——官方推荐日常改用方法版。
再认几门亲戚:not / is / has 与 Until 系列
除了“往上找、往下找、找兄弟”,jQuery 还备了几个更聪明的问法:
not() 是“排除掉某些”,is() 是“判断是不是”(返回 true / false,
不返回集合),has() 是“谁的子孙里有它”。
| 方法 | 问法 | 返回 |
|---|---|---|
not(选择器 / 函数) | 除了这些,剩下的给我 | 集合 |
is(选择器) | 这批元素里有没有符合的?符合一个就算 true | true / false |
has(选择器) | 谁的内部(子孙)藏着匹配元素 | 集合 |
parentsUntil() / nextUntil() / prevUntil() | 边走边找,走到谁为止(不含终点) | 集合 |
add() / addBack() / end() | 把另一批元素、上一环或起点并进来一起操作 | 集合 |
contents() | 连文本节点、注释节点也一并取出(主要在 iframe 场景用) | 集合 |
- 门派名册(我有一份子名单)
- 入门心法(已成)
- 吐纳(未成)
- 剑法(未成)
- 轻功(未成)
点按钮,看每次问中了哪些。
- 修改例 1:要求同一时刻只有一张卡高亮——点击前先把所有卡片的高亮洗掉,再点亮自己。
- 给例 1 的按钮再加一招:标记卡片的同时,把所在卡片的标题也染成朱砂色(
text-danger)。 - 思考题:
parents('.card')与closest('.card')有什么区别?
参考答案 1
“先全局清洗、再局部点亮”是做“唯一选中”的常见套路;
closest 负责把按钮的点击翻译成“所在卡片”的操作。
参考答案 2
closest 向上找到卡片、find 向下找到标题——
上上下下的配合,正是遍历方法的日常。
参考答案 3
parents() 返回所有匹配的祖先(不含自己,可能有多个,由近及远排列);
closest() 从自己开始向上,返回最近的一个匹配(结果零个或一个)。
例 1 里两者都能找到卡片;但如果按钮自己也带 .card 类,
closest 会返回按钮本身,而 parents 不会。找全部用 parents,找最近用 closest。
本式小结
- 元素是一棵树:
parent/parents/children/find上下认亲,siblings/next/prev同级走动; closest从自己向上找最近匹配,是事件委托的黄金搭档;each(function (index, element))逐个点名,index从 0 起,element就是this;filter/first/last/eq缩小包围圈;隐式遍历是“对每个选中元素都动手”的默认行为;not排除、is判断(返回布尔值)、has找“子孙里有的”;nextUntil/prevUntil/parentsUntil走到谁为止(不含终点);addBack()把起点或上一环并回来,add()并入另一批元素。
下一式,我们搭积木——节点的增删改。