在JavaScript中获取父节点最直接的方式是使用parentNode属性,它返回当前节点的直接父节点(可能是元素节点或文档节点),而parentElement则严格限定为元素节点,两者在绝大多数场景下等效,但处理document和documentFragment时有差异。
基础操作:js 取父节点的两种核心方法
使用 parentNode 属性
parentNode是每个DOM节点都具备的属性,包括元素节点、文本节点、注释节点等,它返回当前节点的直接父节点,如果父节点不存在(例如document节点本身),则返回null。
操作示例:
let child = document.getElementById('child');
let parent = child.parentNode;
常见的业务场景包括事件代理中获取触发事件的父级容器,或者在DOM遍历时向上查找指定层级的元素,业内专家指出,在绝大多数DOM操作中,parentNode是默认首选,因为它兼容所有浏览器,包括IE6以上版本。
注意事项:
- 如果当前节点是
document,则parentNode为null。 - 当节点被动态移除但未从内存释放时,
parentNode仍指向原有父节点,但这属于内存泄漏的范畴,与获取逻辑无关。
使用 parentElement 属性
parentElement仅返回元素节点(即nodeType为1的节点),如果父节点不是元素(例如父节点是document或documentFragment),则返回null。
适用场景:
- 需要确保父节点是元素节点,避免文本节点或注释节点干扰。
- 在
SVG或XML文档中,parentElement的兼容性略差于parentNode,因此建议根据具体环境选择。
对比表格:
| 属性 | 返回类型 | 父节点为元素时 | 父节点为文档时 | 浏览器兼容性 |
|---|---|---|---|---|
parentNode |
节点 | 元素节点 | document节点 | 全兼容 |
parentElement |
元素或null | 元素节点 | null | IE9+ |
parentNode 与 parentElement 的核心区别
文档根节点的差异
当父节点是document时,parentNode会返回document节点,而parentElement返回null,这个差异在处理<html>元素时尤为明显:
document.documentElement.parentNode; // 返回 document 节点 document.documentElement.parentElement; // 返回 null
行业共识认为,在绝大多数前端开发中,parentElement的返回值更符合预期,因为开发者通常不需要处理document节点,但如果你的代码需要兼容document作为父节点的情况,则必须使用parentNode。
对文本节点和注释节点的处理
parentNode可以获取到文本节点(如换行符、空格)的父节点,而parentElement则跳过这些非元素节点。
<div id="container"> <span id="child">文本</span> </div>
如果child是span元素,其父节点是div,两者无差别,但假如child是文本节点,parentNode可以获取到其父元素,而parentElement则无法直接使用(因为文本节点没有parentElement属性,但可以通过parentNode获取父元素后再向下遍历)。
实际开发建议:
- 如果你只关心元素节点,优先使用
parentElement,因为它更明确。 - 如果你需要处理任意类型的节点,或者需要兼容老旧浏览器,使用
parentNode更稳妥。
实战场景:获取父节点在DOM操作中的应用
事件委托中的父节点查找
事件委托利用事件冒泡,通常需要获取触发事件的元素的父节点,为一个列表添加点击事件,判断点击的是哪个列表项:
document.getElementById('list').addEventListener('click', function(e) {
let target = e.target;
// 向上查找直至找到 <li> 元素
while (target && target.nodeName !== 'LI') {
target = target.parentNode;
}
if (target) {
console.log('点击了列表项', target);
}
});
这里使用parentNode循环向上查找,直到找到目标元素。parentElement同样可以,但需要额外判断target是否为元素节点。
动态创建元素时获取父级容器
在创建新元素并插入DOM后,有时需要获取其父容器进行后续操作。
let newDiv = document.createElement('div');
document.body.appendChild(newDiv);
let parent = newDiv.parentNode; // 返回 body 元素
这个场景下,parentNode和parentElement结果一致,因为body是元素节点。
与 closest 方法的配合使用
closest方法从当前元素向上遍历,匹配最近的选择器,返回第一个匹配的元素,它本质上是对parentElement循环的封装,使用更简洁:
let parent = element.closest('.container');
但closest必须从元素节点开始调用,且不兼容IE,如果项目需要兼容IE11以下,建议手动使用parentNode循环。
常见问题与误区
使用 parentNode 获取不到父节点
可能的原因:
- 当前节点是
document,parentNode返回null。 - 当前节点被移除后,
parentNode仍指向旧父节点,但此时父节点不在DOM树中,需要通过parentNode.parentNode继续向上查找时可能得到null。 - 节点被创建后尚未插入DOM,此时
parentNode为null。
解决方案:在获取父节点前,先判断节点是否在DOM树中,可以使用document.contains(node)或node.isConnected(现代浏览器)进行检测。
parentElement 在旧浏览器中的兼容性
parentElement在IE9及以上版本支持,如果需要兼容IE8及以下,建议使用parentNode并配合nodeType判断:
function getParentElement(node) {
if (node.parentNode && node.parentNode.nodeType === 1) {
return node.parentNode;
}
return null;
}
这个函数实现了parentElement的降级方案,确保在老旧环境下的行为一致。
Q&A:js 取父节点相关常见问题
问题1:在 iframe 中获取父节点,parentNode 和 top 有区别吗?
在iframe内部,parentNode用于获取DOM层级中的父节点,与window.parent不同。parentNode是DOM属性,用于获取当前元素在文档树中的父元素;window.parent是BOM属性,用于获取父窗口的引用,两者用途不同,不能混淆,如果你需要跨iframe获取父文档中的元素,应使用window.parent.document,然后再使用parentNode操作DOM。
问题2:获取父节点时,如何跳过 text 节点直接获取元素节点?
可以使用parentElement,它只返回元素节点,如果必须使用parentNode,可以手动判断父节点的nodeType是否为1(元素节点),是则返回,否则继续向上查找其父节点,直到找到元素节点为止,这种方法在解析富文本内容时经常用到,可以避免文本节点带来的干扰。
问题3:ShowGetParent 是什么意思?是某个库的方法吗?
“ShowGetParent”通常不是标准JavaScript API或流行库中的方法,它更可能是开发者自定义的辅助函数名,用于演示获取父节点的逻辑,在社区讨论或面试题中,有时会用ShowGetParent作为一个示例函数名,展示如何获取并返回父节点,如果遇到该名称,建议查看具体上下文,它可能是一个封装了parentNode或parentElement的工具函数,用于简化代码或增强兼容性。
掌握parentNode和parentElement的区别,是进行DOM操作的基础,根据具体场景选择合适的属性,可以避免因父节点类型不同引发的bug,在实际项目中,推荐优先使用parentElement,因为它更符合元素操作的预期,同时结合closest方法可以更高效地向上查找特定元素,对于老旧浏览器,使用parentNode配合nodeType检查是最稳妥的兼容方案。
首发原创文章,作者:王坚,如若转载,请注明出处:https://idctop.com/article/536152.html



