基本选择器:三种一刀定位


文档摘要

2.1 基本选择器:三种一刀定位 拿到需求:"把队列里所有候诊条目的字号调小一号。"这是全书中最典型的一类操作,而完成它的第一刀就是选择器。本节是第 2 章的开山节——先把 ID、类、标签这三种最常用的刀法练熟,后面的层级、过滤都是在它们切出的集合上继续加工。 本节摘要:基本选择器只有三种刀法—— 精确命中唯一元素, 圈出同类群体, 撒网抓全部同名标签;逗号可以把多把刀并成一刀。查无匹配时 jQuery 返回空集合而非报错,这一特性决定了后续所有安全写法。 先立一份标本:本教程的演示页面 全书共用下面这个门诊分诊台页面,本节起的所有选择器都在它上面演练。

2.1 基本选择器:三种一刀定位

拿到需求:"把队列里所有候诊条目的字号调小一号。"这是全书中最典型的一类操作,而完成它的第一刀就是选择器。本节是第 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 全文档撒网,逗号是并集。
  • 并集结果按文档序排列,与书写顺序无关。
  • 查无匹配返回空集合而不报错,是 jQuery 安全链式写法的根基,也要求你主动检查 length
  • 原生对照里最容易踩的是"活集合与快照"的差异,循环场景要分清。
  • 选择器宁窄勿宽:标签刀几乎不单独使用,总是作为组合的底层。

有了单点刀法,下一节把视线转向元素之间的关系——顺着父子兄弟的血络去够那些"自己没有名字"的目标。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U