首页
/
行业洞察
/
正文
INDUSTRY INSIGHT · 深度
DOM 元素搜索指南:掌握 JavaScript 教程中的 getElement* 与 querySelector* 方法
📅 2026/10/6 7:29:52
✍️ 爱科研究院
👁 阅读 3,247
文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载本文是 Modern JavaScript Tutorialen.javascript.info中 Searching: getElement*, querySelector* 章节的深度技术解析。文章围绕document.getElementById、querySelectorAll、querySelector、matches、closest与getElementsBy*六大搜索方法展开并结合仓库内配套练习 1-find-elements/task.md 与真实页面 table.html 演示实战用法。读完本文你将能根据id、CSS 选择器、标签名、类名或name属性精准定位任意 DOM 元素并理解活集合live collection与静态集合的本质差异。为什么需要搜索方法在前一章 Walking the DOM03-dom-navigation 中我们了解到DOM 允许我们通过childNodes、parentNode、nextSibling等导航属性在节点之间行走。但这种导航方式只在元素彼此相邻时高效要拿到页面中任意一个元素从document出发沿着导航属性一步步走过去既不现实也不可维护。正如 browser environment01-browser-environment 所介绍的document对象是页面的主要入口点。DOM 提供了另一组搜索方法searching methods让我们可以绕过导航属性直接按特征id、CSS 选择器、标签、类名、name抓取任意元素。这就是本文的主题getElement*与querySelector*两大家族。document.getElementById按 id 精准定位如果一个元素带有id属性无论它在文档中的哪个位置都可以通过document.getElementById(id)拿到它div idelem div idelem-contentElement/div /div script // 获取元素 let elem document.getElementById(elem); // 将其背景设为红色 elem.style.background red; /scriptgetElementById是定位单个元素最直接、性能最优的手段之一在真实项目中它也是官方推荐的取元素方式。名为 id 的全局变量浏览器还提供了一种快捷方式文档中具有id的元素会同时生成一个同名的全局变量直接引用该 DOM 元素div idelem div idelem-contentElement/div /div script // elem 直接引用了 idelem 的 DOM 元素 elem.style.background red; // idelem-content 含连字符不能作为变量名 // ……但可以用方括号通过 window[elem-content] 访问 /script不过如果我们在 JavaScript 中声明了同名变量它就会覆盖这个全局引用div idelem/div script let elem 5; // 现在 elem 是 5不再是 div idelem 的引用 alert(elem); // 5 /script不要在实战中使用以 id 命名的全局变量该行为在 HTML 规范 中有描述但主要是为了兼容旧代码。浏览器试图把 JS 命名空间和 DOM 命名空间混合起来帮我们这对内联在 HTML 里的简单脚本没问题但通常不是好做法可能存在命名冲突而且当读者只看 JS 代码、看不到 HTML 时很难判断这个变量从何而来。教程里为了简洁会直接用id引用元素但真实项目中document.getElementById才是首选方法。id必须是唯一的一个文档中只能有一个元素拥有给定的id。如果出现多个相同id使用它的方法行为将不可预测——例如document.getElementById可能随机返回其中任意一个。请务必遵守id唯一的规则。只能在document上调用getElementById该方法只能作用于document对象它会在整个文档中查找给定的id。不存在anyElem.getElementById这种写法。querySelectorAll最强通用的 CSS 选择器搜索elem.querySelectorAll(css)是用途最广的方法返回elem内部所有匹配给定 CSS 选择器的元素。例如找出所有作为最后一个子元素的liul liThe/li litest/li /ul ul lihas/li lipassed/li /ul script let elements document.querySelectorAll(ul li:last-child); for (let elem of elements) { alert(elem.innerHTML); // test, passed } /script这个方法之所以强大是因为任何 CSS 选择器都可以用类型选择器、类选择器、属性选择器、后代组合、子组合、兄弟组合等一应俱全。伪类同样支持CSS 选择器中的伪类如:hover、:active也受支持。例如document.querySelectorAll(:hover)会返回当前指针悬停之上的元素集合按嵌套顺序从最外层的html到最内层。querySelector只取第一个匹配项elem.querySelector(css)返回给定 CSS 选择器的第一个匹配元素。换句话说它的结果等价于elem.querySelectorAll(css)[0]但后者会先找出全部匹配元素再取其一而elem.querySelector只查找一个。因此它更快写起来也更短。在仓库配套练习的解法 solution.md 中可以清晰看到这种替代关系// 5. 表单中的第一个 input form.getElementsByTagName(input)[0] // 或者 form.querySelector(input)当只需要一个元素时querySelector是比getElementsByTagName(...)[0]更简洁、更现代的选择。matches只判断、不搜索前面几种方法都在搜索 DOM而elem.matches(css)不做任何查找它只检查elem是否匹配给定的 CSS 选择器返回true或false。当我们遍历元素集合例如数组或document.body.children并想筛选出感兴趣的元素时这个方法非常方便a hrefhttp://example.com/file.zip.../a a hrefhttp://ya.ru.../a script // 这里可以是任何集合不限于 document.body.children for (let elem of document.body.children) { if (elem.matches(a[href$zip])) { alert(The archive reference: elem.href); } } /script上例中a[href$zip]是属性选择器$表示以……结尾因此能精确筛出指向.zip压缩包的链接。matches常与事件委托配合使用在e.target上判断点击来源是 DOM 编程中的高频工具。closest向祖先链向上查找元素的**祖先ancestors**包括父元素、父元素的父元素依此类推最终连成从该元素到文档顶端的链条。elem.closest(css)查找最近的、匹配给定 CSS 选择器的祖先。注意elem自身也包含在查找范围内。也就是说closest从元素出发逐级向上检查每个父节点一旦某级匹配选择器搜索立即停止并返回该祖先h1Contents/h1 div classcontents ul classbook li classchapterChapter 1/li li classchapterChapter 2/li /ul /div script let chapter document.querySelector(.chapter); // LI alert(chapter.closest(.book)); // UL alert(chapter.closest(.contents)); // DIV alert(chapter.closest(h1)); // nullh1 不是祖先 /scriptclosest是处理嵌套结构如菜单、列表、卡片中点击了哪个容器这类问题的利器与事件委托配合可以大大简化代码。getElementsBy*按标签、类名、name 搜索此外还有一组按标签、类名等查找节点的方法。如今它们大多属于历史遗留因为querySelector更强大且书写更短这里讲解它们主要为了完整性——你仍会在旧脚本中见到它们elem.getElementsByTagName(tag)—— 按给定标签查找元素并返回集合tag参数也可以是星号*表示任意标签。elem.getElementsByClassName(className)—— 返回拥有给定 CSS 类的元素。document.getElementsByName(name)—— 按name属性在整个文档范围内查找元素极少使用。基础用法// 获取文档中所有 div let divs document.getElementsByTagName(div);在指定元素内部继续搜索也同样自然。下面示例查找表格中的所有input标签table idtable tr tdYour age:/td td label input typeradio nameage valueyoung checked less than 18 /label label input typeradio nameage valuemature from 18 to 50 /label label input typeradio nameage valuesenior more than 60 /label /td /tr /table script let inputs table.getElementsByTagName(input); for (let input of inputs) { alert( input.value : input.checked ); } /script常见坑一别忘字母 s新手常把getElement**s**ByTagName写成getElementByTagName。规律如下getElementById中没有s因为它只返回单个元素getElementsByTagName返回元素集合所以里面有s。常见坑二返回的是集合不是元素另一个普遍错误是试图直接给集合赋值// 不生效 document.getElementsByTagName(input).value 5;这样写不会生效因为拿到的是一组 input 的集合赋值被施加在集合本身而非集合内的元素上。正确做法是遍历集合或先按下标取出元素再赋值// 正确假设存在 input document.getElementsByTagName(input)[0].value 5;按 name 与按 class 的组合示例下面的例子同时演示了getElementsByName文档级与getElementsByClassName元素级form namemy-form div classarticleArticle/div div classlong articleLong article/div /form script // 按 name 属性查找 let form document.getElementsByName(my-form)[0]; // 在 form 内部按 class 查找 let articles form.getElementsByClassName(article); alert(articles.length); // 2找到两个 class 含 article 的元素 /script活集合Live collections与静态集合所有getElementsBy*方法返回的都是活集合live collection这类集合始终反映文档的当前状态当文档变化时会自动更新。下面例子中有两段脚本第一段创建了对div集合的引用此时其长度为1浏览器解析到又一个div后运行的第二段脚本看到长度为2。divFirst div/div script let divs document.getElementsByTagName(div); alert(divs.length); // 1 /script divSecond div/div script alert(divs.length); // 2 /script与之相反querySelectorAll返回静态集合static collection它就像元素的一个固定数组。若换用它两段脚本输出的都是1divFirst div/div script let divs document.querySelectorAll(div); alert(divs.length); // 1 /script divSecond div/div script alert(divs.length); // 1 /script现在差异一目了然文档中出现新的div后静态集合并没有随之增长。这一特性在动态页面中尤为关键——如果你先取得集合、之后 DOM 又发生变化getElementsBy*的活集合会立即反映新增/删除的节点而querySelectorAll的快照则保持不变。实战演练查找表格与表单中的元素仓库为本章配有一道完整练习 1-find-elements/task.md其页面 table.html 同时包含表单与表格结构。练习要求完成六项查找idage-table的表格该表格内所有label元素共 3 个表格内第一个td含 Age 字样namesearch的表单该表单中的第一个input该表单中的最后一个input。官方解法 solution.md 展示了每种目标的多条可行路径恰好覆盖了本文全部方法// 1. idage-table 的表格 let table document.getElementById(age-table) // 2. 表格内所有 label 元素 table.getElementsByTagName(label) // 或 document.querySelectorAll(#age-table label) // 3. 表格内第一个 td含 Age 字样 table.rows[0].cells[0] // 或 table.getElementsByTagName(td)[0] // 或 table.querySelector(td) // 4. namesearch 的表单 // 假设文档中只有一个 namesearch 的元素 let form document.getElementsByName(search)[0] // 或专门针对表单 document.querySelector(form[namesearch]) // 5. 表单中的第一个 input form.getElementsByTagName(input)[0] // 或 form.querySelector(input) // 6. 表单中的最后一个 input let inputs form.querySelectorAll(input) // 找到全部 input inputs[inputs.length - 1] // 取最后一个注意第 3 问中table.rows[0].cells[0]用到了表格特有的rows/cells集合属性这是getElementsBy*之外的另一种快捷路径。可见同一查找目标往往存在多种等价实现理解每种方法的特性是否活集合、是否支持复杂选择器、调用对象限制才能选出最合适的方案。总结DOM 中搜索节点共有6 个主要方法方法按什么搜索能否在元素上调用是否活集合querySelectorCSS 选择器✔-querySelectorAllCSS 选择器✔-getElementByIdid--getElementsByNamename-✔getElementsByTagName标签或*✔✔getElementsByClassNameclass✔✔使用频率最高的是querySelector与querySelectorAll但getElement(s)By*在特定场景仍有用武之地也常见于旧脚本。除此之外还有两个高频辅助方法elem.matches(css)—— 检查elem是否匹配给定 CSS 选择器elem.closest(css)—— 查找最近的、匹配给定 CSS 选择器的祖先elem自身也会被检查。最后再补充一个用于判断父子关系的方法有时很实用elemA.contains(elemB)—— 若elemB在elemA内部是elemA的后代或elemA elemB返回true。至此从getElementById的单点精准定位到querySelectorAll的任意 CSS 选择器批量抓取再到matches/closest的关系判断你已经掌握了在 document 章节2-ui/1-document 后续内容中操作页面元素的全部定位武器。下一章 basic-dom-node-properties05-basic-dom-node-properties 将进一步介绍这些元素节点自身的属性体系。赞分享文档/教程前端【免费下载链接】en.javascript.infoModern JavaScript Tutorial项目地址https://gitcode.com/gh_mirrors/en/en.javascript.info点击查看免费下载相关推荐JavaScript教程DOM元素搜索方法详解JavaScript教程DOM元素搜索方法详解 在Web开发中DOM元素搜索是JavaScript操作页面元素的基础。本文将全面介绍JavaScript中常文档教程前端JavaScript DOM 元素搜索方法详解JavaScript DOM 元素搜索方法详解 前言 在 JavaScript 中操作 DOM 时查找元素是最基础也是最重要的操作之一。本文将全面介绍 Jav文档/教程前端JavaScript DOM 元素搜索方法详解JavaScript DOM 元素搜索方法详解 前言 在 JavaScript 中操作网页元素时首先需要找到这些元素。DOM 提供了多种搜索元素的方法每种方上一篇AstroWind社区贡献如何参与开源项目开发下一篇GLM-4-9B-Chat性能优化技巧10个提升推理速度的方法创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📌 标签:
工业官网
设计趋势
AI 建站
SEO
获取完整报告 →
RELATED ARTICLES
推荐阅读
2026/10/6 7:29:52
KubeVirt 使用 kind-1.36 Provider 部署 Kubernetes 1.36 测试集群实战指南
2026/10/6 7:29:52
Forth 语言快速入门:基于 learnxinyminutes-docs 的栈式编程实战指南
2026/10/6 7:29:52
QtScrcpy 投屏控制实操手册:USB 与无线连接、多设备批量操作、键鼠映射一次讲透
2026/10/6 8:14:56
QT 从零写一个 Notepad:桌面记事本开发实战与避坑指南
2026/10/6 8:14:56
Android Studio Chipmunk Canary 2 实战:安装配置、项目移植与避坑指南
2026/10/6 8:14:56
本地运行深度学习画风迁移:从零跑通NST实战指南
2026/10/6 8:14:56
KMeans聚类实战:用Iris数据集理解算法边界与工程陷阱
2026/10/6 8:14:56
MFC Dialog2图片以鼠标为中心缩放:坐标推导与避坑指南
2026/10/6 8:09:56
第088篇 协程入门:suspend 到底挂起了谁
2026/10/6 1:04:29
搭建无线EEG采集前端:BW16+ESP32-CYD实时波形显示实战
2026/10/6 1:04:29
CH10D功放芯片DIY音箱实战:从选型到调试的完整指南
2026/10/6 1:04:29
视频序列目标跟踪实战:解决ID跳变与遮挡丢失
2026/10/5 4:43:56
Jev+Agent接管浏览器:browser-use实战与jev-ultrafast性能优化
2026/10/6 4:47:52
多智能体集群实战:DeepAgents编排、MCP与A2A协议及Skills体系
2026/10/5 13:05:37
hindsight:面向LLM应用的事后可观测性工程实践
2026/10/5 20:28:25
我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频
2026/10/5 20:28:23
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证
2026/10/5 20:28:21
2026 大模型集体涨价:用 Python 做企业 Token 成本测算与选型避坑(附配置)