优先使用带业务含义的自定义 data 属性,如 [data-status='draft'];结合伪类如 :not(:disabled) 做复合判断;用 ~=、^=、$=、*= 处理动态值;注意 dom 加载时机、大小写及特殊字符转义。

用 querySelector 配合属性选择器,核心是绕开不稳定的 class 或结构层级,直接抓取元素自带的、业务语义明确的状态标识——比如 data-status、data-id、disabled、aria-checked 等。这类属性通常由框架或业务逻辑写入,变动小、意图清,比依赖视觉类名更可靠。
优先使用带业务含义的自定义 data 属性
真实业务中,DOM 常通过 data-* 标记状态,例如:
-
data-status="draft"表示草稿态 -
data-step="3"表示流程第三步 -
data-user-role="admin"区分权限
定位时直接写:document.querySelector("[data-status='draft']")document.querySelector("button[data-step='3'][data-active='true']")
注意:多个属性条件并列,不用空格或逗号,直接连写即可,表示“同时满足”。
结合伪类与属性做复合状态判断
单靠属性还不够?加伪类进一步收窄范围:
- 找未禁用且处于 pending 状态的提交按钮:
document.querySelector("button[data-status='pending']:not(:disabled)") - 找已选中又带错误标记的复选框:
document.querySelector("input[type='checkbox'][aria-invalid='true']:checked") - 找当前激活的 tab 页签(可能 class 动态切换,但
aria-selected="true"更稳):document.querySelector("[role='tab'][aria-selected='true']")
处理属性值含空格或动态前缀的场景
有些属性值不是精确匹配,比如 class="btn btn-primary is-loading" 或 data-id="api-order-123":
- 匹配空格分隔的单词(类似 class)用
~="val":document.querySelector("[class~='is-loading']")可命中上面例子 - 匹配开头(如 API ID)用
^="prefix":document.querySelector("[data-id^='api-order-']") - 匹配结尾用
$="suffix",包含子串用*="part"
避免常见陷阱,确保查得到
即使选择器看起来对,也可能返回 null:
- DOM 还没加载完就执行?把脚本放











