通配符选择器 * 匹配 DOM 中所有元素节点,不区分标签、属性或状态,但不匹配文本节点、伪元素及 Document 等非元素节点;常用于 CSS 全局重置或 JS 调试遍历,性能敏感时应优先使用更精确的选择器。

通配符选择器就是 *,它匹配页面中所有元素
它不区分标签、属性或状态,只要 DOM 树里存在,就命中。比如 document.querySelectorAll('*') 会返回包含 html、head、body、所有文本节点(注意:实际中 * 不匹配文本节点,只匹配元素节点)、div、p、span 等所有元素节点的 NodeList。
* 在 CSS 和 JS 中行为一致,但使用场景差异大
CSS 中写 * { margin: 0; padding: 0; } 是全局重置常见起点;JS 中用 document.querySelectorAll('*') 主要用于调试、遍历统计或动态注入逻辑。但要注意:
-
querySelectorAll('*')返回的是**所有元素节点**,不含 Document、DocumentFragment、Text 节点 - 性能敏感场景慎用——DOM 超过千级节点时,
*的遍历开销明显高于具体选择器(如div或[data-id]) - 在 Shadow DOM 内部,
*只匹配该 shadow root 下的元素,不会穿透到 light DOM
替代方案更常用:按需缩小范围,避免无差别匹配
真正需要“所有元素”是少数情况。多数时候你其实想要:
- 所有可见容器:
document.querySelectorAll('div, section, article, main, aside, footer, header') - 所有带特定属性的元素:
document.querySelectorAll('[data-track], [aria-label]') - 排除某些标签(比如跳过 script/style):
Array.from(document.querySelectorAll('*')).filter(el => !['SCRIPT', 'STYLE', 'NOSCRIPT'].includes(el.tagName)) - 递归子树遍历(比
*更可控):function walk(el) { /* 处理 el */; el.children.forEach(walk); }
容易忽略的边界:伪元素和动态插入内容不被 * 选中
* 只匹配真实存在于 DOM 树中的**元素节点**。这意味着:
- CSS 伪元素(如
::before、::selection)永远无法用*或任何选择器直接选中或操作 - 通过
innerHTML或appendChild动态插入的元素,只有插入后才进入*的匹配范围;插入前的字符串模板不算 -
document.querySelectorAll('*')不包含document自身,也不包含document.documentElement以外的文档对象(如document.doctype)
真正需要通配匹配时, 确实最简;但多数实际需求背后,藏着更精确的意图——先想清楚“要所有元素”是不是真必要,往往比怎么写 更关键。










