最简洁高效的方式是使用 dom 元素的 contains() 方法,调用形式为 parent.contains(child),返回布尔值;仅支持有效元素节点,方向必须为“父查子”,不跨 shadow dom,且两节点须同属一个 document。

直接用 DOM 元素的 contains() 方法,这是最简洁、高效、原生的方式。
contains() 的基本用法
调用形式是:parent.contains(child),返回布尔值。
- 如果
child是parent自身,或其任意后代(子、孙、曾孙……),返回 true - 如果
child为null、不在同一文档树中、或根本不是节点对象,返回 false - 必须是两个有效的 DOM 元素节点(
nodeType === 1),不能传字符串选择器、文本节点或document
常见错误和注意事项
容易出错的地方往往不在语法,而在调用逻辑和节点有效性。
-
方向不能反:只能是“父查子”,不能写
child.contains(parent)—— 子节点不可能包含祖先 -
不跨 Shadow DOM:若目标节点在 Shadow Root 内部,
contains()默认返回false,需手动遍历或结合composed: true的事件路径处理 -
同文档前提:两个节点必须属于同一个
document,iframe 中的节点对主文档调用contains()会失败 - 兼容性好:IE9 及以上均支持,无需 polyfill
替代方案对比(不推荐日常使用)
虽然可用,但明显更冗长或低效:
-
手动遍历
parentNode:循环向上找直到null或匹配到父节点,代码多、性能差、易漏边界 -
用
compareDocumentPosition():返回位掩码,需判断第 4 位(DOCUMENT_POSITION_CONTAINED_BY),可作为contains()不可用时的降级方案(如极老 Firefox),但现代已无必要 -
CSS 选择器模拟:比如
parent.querySelector(selector) !== null,本质是查找而非判断包含关系,且无法处理动态节点或非元素节点
实用小例子
判断点击是否发生在某个弹窗内部,常用于点击外部关闭:
document.addEventListener('click', e => {
const modal = document.getElementById('modal');
if (modal && !modal.contains(e.target)) {
modal.classList.remove('show');
}
});
这里 e.target 是被点击的真实节点,modal.contains(e.target) 精准覆盖 modal 自身及其所有子元素,包括按钮、文字、空 div 等。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











