先说几个核心判断:DOM节点遍历与搜索是JavaScript操作页面的基本功,但许多初学者在节点类型上容易犯错。你以为是查找元素,结果返回的却是文本节点,这种情况非常常见。关键在于理解节点关系和方法适用场景——并非所有方法都返回元素节点,有些返回包含文本、注释在内的全部节点,使用前务必确认返回值类型。

接下来,我们将逐一解析每种方法的特性与适用场景,帮助您彻底掌握DOM节点遍历技巧。
使用 parent/child/next/previous 系列属性遍历直接关系节点
注意,这些属性访问的是“直接相邻”的节点,不会跳过中间层级,而且返回值可能是元素节点(Element),也可能是文本节点(Text)或注释节点(Comment)。也就是说,如果不熟悉节点类型,很容易踩坑。
- parentNode:获取父节点,几乎所有节点都有(除 document 本身)。一个小细节:document.documentElement.parentNode 是 document,而 document.parentNode 是 null。
- childNodes:返回 NodeList,包含所有子节点(元素、文本、注释)。注意它不是 HTMLCollection,不支持 forEach,要么转成数组,要么使用 for 循环。
- children:这个属性更友好——只返回子元素节点(Element),返回 HTMLCollection,可以直接调用 forEach。日常开发中,用它比 childNodes 频繁得多。
- firstChild / lastChild:这两个是常见陷阱。因为空白在 DOM 里也算文本节点,所以经常返回空白文本,不是你想要的那个元素。firstElementChild / lastElementChild 则更安全,只查找元素节点。
- nextSibling / previousSibling:同样可能返回文本节点。nextElementSibling / previousElementSibling 只返回相邻元素,推荐优先使用。
利用 querySelector 与 querySelectorAll 精准定位元素节点
这两个方法可以说是现代开发者的标配。基于 CSS 选择器语法,功能强大,语义清晰,而且无需担心实时性问题。
- querySelector(selector):返回匹配的第一个元素节点,未找到返回 null。
- querySelectorAll(selector):返回静态 NodeList(非实时),包含所有匹配的元素节点。
- 支持复杂选择器:
div#main .item[data-active="true"]、:not(.disabled) > button,这些都能使用。 - 可以在任意元素上调用,不限于 document。例如
container.querySelector('input')实现局部查找,效率更高。
通过 getElementsBy 系列方法获取动态集合(实时更新)
这类方法返回 HTMLCollection(实时更新),适合需要响应 DOM 变化的场景,但选择器能力有限。
- getElementsByTagName(tagName):按标签名查找,
"*"匹配所有元素。 - getElementsByClassName(className):按 class 查找,参数是字符串(不要加点),支持多个 class 用空格分隔。
- getElementsByName(name):仅对具有 name 属性的元素有效(如 form、input、img)。
- 需要警惕的是:它们不支持 CSS 伪类或属性选择器,而且返回的是实时集合——后续新增匹配元素会自动加入结果中。如果没有意识到这一点,可能会在遍历过程中遭遇意外。
借助 matches 与 closest 实现条件判断与向上遍历
这两个方法常用于事件委托和状态判断,逻辑清晰、性能良好,省去了很多手写循环的麻烦。
- element.matches(selector):判断当前元素是否匹配给定选择器,返回布尔值。用它替代旧式 tagName/class 判断,代码更简洁。
- element.closest(selector):从自身开始向上查找,返回第一个匹配的祖先元素(含自身),找不到返回 null。比循环 parentNode + matches 更简洁安全。
- 典型用法:
event.target.closest('button')在事件监听中精准识别操作目标——你点击的到底是按钮还是按钮里的图标?这个函数能帮你搞定。
