如何检查一个 DOM 元素是否是另一个 DOM 元素的子元素?是否有任何内置方法?例如,类似于:
if (element1.hasDescendant(element2))
或者
if (element2.hasParent(element1))
如果没有,那么任何想法如何做到这一点?它还需要跨浏览器。我还应该提到,子级可以嵌套在父级之下许多级别。
如何检查一个 DOM 元素是否是另一个 DOM 元素的子元素?是否有任何内置方法?例如,类似于:
if (element1.hasDescendant(element2))
或者
if (element2.hasParent(element1))
如果没有,那么任何想法如何做到这一点?它还需要跨浏览器。我还应该提到,子级可以嵌套在父级之下许多级别。
您应该使用Node.contains
,因为它现在是标准的并且在所有浏览器中都可用。
https://developer.mozilla.org/en-US/docs/Web/API/Node.contains
更新:现在有一种本地方式来实现这一点。Node.contains()
. 在评论和下面的答案中也提到了。
旧答案:
使用该parentNode
属性应该有效。从跨浏览器的角度来看,它也非常安全。如果已知该关系深一层,您可以简单地检查一下:
if (element2.parentNode == element1) { ... }
如果子级可以任意嵌套在父级内部,则可以使用类似于以下的函数来测试关系:
function isDescendant(parent, child) {
var node = child.parentNode;
while (node != null) {
if (node == parent) {
return true;
}
node = node.parentNode;
}
return false;
}
我只需要分享“我的”。
虽然概念一样亚萨的答案(受益于相同的跨浏览器的兼容性,甚至IE6),这是一个很多更小,非常适合对尺寸为溢价和/或当它不需要经常。
function childOf(/*child node*/c, /*parent node*/p){ //returns boolean
while((c=c.parentNode)&&c!==p);
return !!c;
}
..或作为单行(仅 64 个字符!):
function childOf(c,p){while((c=c.parentNode)&&c!==p);return !!c}
用法:
childOf(child, parent)
返回布尔值true
| false
.
说明:
while
只要 while 条件的计算结果为true
。
该&&
(AND)运算符返回此布尔真/假后评估的左侧和右侧,但只有当左手侧是真实的(left-hand && right-hand
)。
左侧(的&&
)是:(c=c.parentNode)
。
这将首先将parentNode
of分配c
给c
,然后 AND 运算符会将结果评估c
为布尔值。
由于在没有父节点时parentNode
返回null
并null
转换为false
,因此当没有更多父节点时,while 循环将正确停止。
右侧(的&&
)是:c!==p
。
的!==
比较操作符是“不完全等于”。因此,如果孩子的父母不是父母(您指定的),则其计算结果为true
,但如果孩子的父母是父母,则计算结果为false
。
因此,如果 c!==p
计算结果为 false,则&&
运算符false
作为 while 条件返回,while 循环停止。(注意不需要 while-body 并且;
需要结束分号。)
因此,当 while 循环结束时,c
它要么是一个节点(不是null
),要么是它找到父节点时,要么是null
(当循环运行到最后而没有找到匹配项时)。
因此,我们简单地将return
这个事实(转换为布尔值,而不是节点)与:return !!c;
: !
(NOT
运算符) 反转布尔值(true
成为false
和反之亦然)。在它可以反转该值之前
!c
将c
(节点或空)转换为布尔值。因此,添加第二个!
( !!c
) 会将这个 false 转换回true(这就是为什么!!
经常使用double来“将任何内容转换为布尔值”)。
额外:
该函数的主体/有效负载非常小,根据情况(例如当它不经常使用并且在代码中只出现一次时),甚至可以省略该函数(包装)而只使用 while 循环:
var a=document.getElementById('child'),
b=document.getElementById('parent'),
c;
c=a; while((c=c.parentNode)&&c!==b); //c=!!c;
if(!!c){ //`if(c)` if `c=!!c;` was used after while-loop above
//do stuff
}
代替:
var a=document.getElementById('child'),
b=document.getElementById('parent'),
c;
function childOf(c,p){while((c=c.parentNode)&&c!==p);return !!c}
c=childOf(a, b);
if(c){
//do stuff
}
另一个没有提到的解决方案:
var parent = document.querySelector('.parent');
if (parent.querySelector('.child') !== null) {
// .. it's a child
}
元素是否是直接子元素并不重要,它可以在任何深度工作。
或者,使用.contains()
方法:
var parent = document.querySelector('.parent'),
child = document.querySelector('.child');
if (parent.contains(child)) {
// .. it's a child
}
您可以使用contains 方法
var result = parent.contains(child);
或者你可以尝试使用compareDocumentPosition()
var result = nodeA.compareDocumentPosition(nodeB);
最后一个更强大:它返回一个位掩码作为结果。