2.1 基本选择器:三种一刀定位 拿到需求:"把队列里所有候诊条目的字号调小一号。"这是全书中最典型的一类操作,而完成它的第一刀就是选择器。本节是第 2 章的开山节——先把 ID、类、标签这三种最常用的刀法练熟,后面的层级、过滤都是在它们切出的集合上继续加工。 本节摘要:基本选择器只有三种刀法—— 精确命中唯一元素, 圈出同类群体, 撒网抓全部同名标签;逗号可以把多把刀并成一刀。查无匹配时 jQuery 返回空集合而非报错,这一特性决定了后续所有安全写法。 先立一份标本:本教程的演示页面 全书共用下面这个门诊分诊台页面,本节起的所有选择器都在它上面演练。
拿到需求:"把队列里所有候诊条目的字号调小一号。"这是全书中最典型的一类操作,而完成它的第一刀就是选择器。本节是第 2 章的开山节——先把 ID、类、标签这三种最常用的刀法练熟,后面的层级、过滤都是在它们切出的集合上继续加工。
本节摘要:基本选择器只有三种刀法——
#id精确命中唯一元素,.class圈出同类群体,tagname撒网抓全部同名标签;逗号可以把多把刀并成一刀。查无匹配时 jQuery 返回空集合而非报错,这一特性决定了后续所有安全写法。
全书共用下面这个门诊分诊台页面,本节起的所有选择器都在它上面演练。建议真的把它存成页面跑起来:
<body> <header id="topbar" class="bar"> <h1 class="logo">门诊分诊台</h1> <button id="refresh" class="btn">刷新队列</button> </header> <main id="ward" class="panel"> <h2 class="panel-title">候诊队列</h2> <ul id="queue" class="list"> <li class="item urgent" data-vital="high">张三 · 心悸</li> <li class="item stable" data-vital="mid">李四 · 扭伤</li> <li class="item stable" data-vital="mid">王五 · 复诊</li> <li class="item done" data-vital="low">赵六 · 取药</li> </ul> </main> </body>

三种刀在标本页上的实际命中情况:
$('#queue').length; // 1:ID 在合法文档里唯一,必然至多一个 $('.stable').length; // 2:李四、王五,所有带 stable 类的元素 $('li').length; // 4:全文档所有 li,不分区域 $('.item, .btn').length; // 5:并集——四个条目加一个按钮
并集写法要留意一个细节:结果顺序按文档中出现位置排列,与你书写选择器的顺序无关。$('.btn, .item') 和 $('.item, .btn') 返回的集合内容与顺序完全一致。
初学者常被这个特性救了一命而不自知。原生按 ID 取元素,查不到返回 null,紧接着读属性就是一次报错:
var el = document.getElementById('ghost'); el.textContent; // 报错:Cannot read properties of null var $el = $('#ghost'); $el.length; // 0:返回空 jQuery 对象,不报错 $el.addClass('x'); // 空集合上调用方法:静默无操作,依然不报错
这解释了 jQuery 风格里"先选后改"可以放心连写的原因,但也埋着新坑:选择器拼错时页面安静得像什么都没发生。所以生产代码里养成第一步看长度的习惯:
var $target = $('#quene'); // 手滑拼错了 queue if ($target.length === 0) { console.warn('定位失败:检查选择器拼写'); }
| jQuery 写法 | 对应的原生写法 | 返回值差异 |
|---|---|---|
$('#queue') |
document.getElementById('queue') |
jQuery 恒返回集合;原生查不到给 null |
$('.stable') |
document.querySelectorAll('.stable') |
前者是带方法的 jQuery 对象,后者是静态 NodeList |
$('li') |
document.getElementsByTagName('li') |
原生这个返回活的 HTMLCollection,文档变了会自动更新 |
第三行的差异最容易被忽略:原生按标签查询拿到的是"活集合",往文档里再插一个 li,集合长度会自己变;jQuery 集合则是查询瞬间的快照,插多少都与你手里这个对象无关。写循环时把这一点搞反,是"循环次数不对"类毛病的常见来源。
现代 jQuery 内部就是把这三把刀直接交给原生引擎执行——ID 查询走 getElementById,其余走 querySelectorAll。真正自研选择器引擎的年代是为了补老 IE 的缺,如今这份复杂度已经还给了浏览器。
在标本页控制台里依次执行,对照注释里的预期:
console.log($('#topbar .logo').text()); // 门诊分诊台 console.log($('.item').length); // 4 console.log($('li.stable').length); // 2:标签刀与类刀组合 console.log($('#queue, #topbar').length); // 2:并集 console.log($('#nope').length); // 0:查无此人
$('li.stable') 这种"标签 + 类"的连写是基本刀的第一次组合:先撒网抓全部 li,再在网里只留带 stable 类的。组合的完整规则下一节展开。
#id 唯一命中、.class 批量圈选、tag 全文档撒网,逗号是并集。length。有了单点刀法,下一节把视线转向元素之间的关系——顺着父子兄弟的血络去够那些"自己没有名字"的目标。