matches()用[attr]可精准判断节点自身是否声明指定属性,不检查子元素、不校验属性值;需避免*、:has()等无效写法,组合选择器可一次性验证多条件。

直接用 matches() 判定节点自身是否具备指定属性,关键在于使用属性选择器(如 [data-id]、[disabled]),它只检测当前节点是否拥有该属性,不会向下检查子元素。
用属性存在选择器判断属性是否存在
matches() 接收一个 CSS 选择器字符串,当传入 [attr] 形式时,仅校验当前节点是否声明了该属性(不管值是什么)。
-
el.matches('[required]')→ 返回true如果el有required属性(哪怕required="false"或required="") -
el.matches('[data-user-id]')→ 只看有没有这个属性名,不关心值是否为空或是否为数字 - 注意:不能写成
el.matches('div[title]')来限定标签——除非你明确需要同时匹配标签和属性,否则多余限定可能误判(比如目标是span[title]却传了div[title])
区分「属性存在」和「属性值匹配」
若需进一步校验属性值,可用带引号的属性选择器,但要注意值必须完全一致(含空格):
-
el.matches('[type="submit"]')→ 匹配<button type="submit">,不匹配type=" submit "或type="SUBMIT" -
el.matches('[class~="btn"]')→ 用~可匹配空格分隔的 class 值之一(类似classList.contains()) -
el.matches('[data-state^="lo"]')→ 用^=匹配开头为指定字符串的值
避免常见误区
以下写法无法达到“只查自身属性”的目的,需规避:
- ❌
el.matches('*[attr]')——*是冗余的,且易引发误解;直接用[attr]更清晰 - ❌
el.matches(':has([attr])')——:has()是父选择器,会向上查找,且目前在matches()中基本不被支持(多数浏览器尚未实现) - ❌ 混淆
hasAttribute()和matches():前者更轻量、语义更直接;后者优势在于可组合复杂条件,例如[data-role="menu"][aria-expanded="true"]
实用组合示例
一次性验证多个属性约束,比链式调用更简洁:
-
button.matches('[type="submit"][disabled][data-pending]')→ 确认按钮是提交类型、已禁用、且带 pending 标记 -
input.matches('[required]:not([readonly])')→ 必填但未设为只读(冒号表示伪类,not是合法伪类) - 注意:所有条件都在同一节点上求值,天然不涉及子元素

















