closest 和 matches 是高效判断与查找祖先元素的两个核心方法:closest 从自身向上查找第一个匹配选择器的祖先(含自身),matches 则仅判断当前元素是否匹配选择器,二者组合可精准定位并条件过滤,替代易错的手动遍历。

closest 和 matches 是现代 DOM 操作中高效判断与查找祖先元素的两个核心方法,配合使用能避免手动遍历父节点,代码更简洁、性能更好。
closest:从自身开始向上查找第一个匹配的祖先
它从当前元素自身开始,逐级向上(包括自己)查找符合 CSS 选择器的第一个祖先元素。没找到则返回 null。
- 用法:
element.closest(selector) - 支持任意合法 CSS 选择器(类名、ID、属性、伪类等)
- 注意:它包含自身——如果当前元素就匹配,直接返回它
例如:button.closest('form') → 找到按钮所在最近的 <form></form>(可能是父、祖父,甚至就是 button 自身,如果它被设为 form 标签)。
matches:判断当前元素是否匹配某个选择器
matches 不查找,只做布尔判断:当前元素是否满足给定的选择器条件。
- 用法:
element.matches(selector),返回 true 或 false - 常用于事件委托中快速过滤目标元素,或配合循环手动向上检查
- 兼容写法可加前缀:
element.matches || element.msMatchesSelector || element.webkitMatchesSelector
例如:event.target.matches('.submit-btn') → 判断点击的是否是提交按钮;el.matches('[data-role="modal"]') → 判断该元素是否有 data-role="modal" 属性。
组合使用:精准定位 + 条件过滤
当需要“找到某个特定类型的祖先,且它还满足额外条件”时,closest 可先定位,再用 matches 验证细节;或者反过来,用 matches 快速跳过不相关分支,再调 closest 精确收口。
- 场景1:查找带特定 class 的最近
section,且它还有data-loaded="true"el.closest('section').matches('[data-loaded="true"]') && el.closest('section') - 场景2:事件代理中,只处理来自
.card内部、且目标是.delete按钮的点击if (e.target.matches('.delete') && e.target.closest('.card')) { ... }
替代手动遍历:更安全、更语义化
过去常用 while (parent) { if (parent.matches(...)) break; parent = parent.parentNode; },容易漏判自身、忘记 null 检查、逻辑冗长。closest 内置了这些边界处理,matches 提供了声明式判断——两者结合,让祖先关系判断变得直观可靠。










