如何检查一个DOM元素是否是另一个DOM元素的子元素?这有什么内置的方法吗?例如,类似于:
if (element1.hasDescendant(element2))
要么
if (element2.hasParent(element1))
如果没有那么任何想法如何做到这一点?它还需要跨浏览器。我还应该提到,孩子可以嵌套在父母以下的许多级别。
使用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;
}
您应该使用Node.contains
,因为它现在已成为所有浏览器的标准版本。
https://developer.mozilla.org/en-US/docs/Web/API/Node.contains
我只需要分享'我的'。
虽然在概念上与Asaph's answer相同(受益于相同的跨浏览器兼容性,即使是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)
返回boolean true
| false
。
说明:
只要while条件评估为while
,true
就会进行评估。
在评估左侧和右侧之后,&&
(AND)运算符返回此布尔值true / false,但仅在左侧为真时(left-hand && right-hand
)。
左侧(&&
)是:(c=c.parentNode)
。
这将首先将parentNode
的c
分配给c
,然后AND运算符将评估生成的c
作为布尔值。
由于parentNode
返回null
,如果没有父亲离开并且null
被转换为false
,那么当没有更多父母时,while循环将正确停止。
右边(&&
)是:c!==p
。
!==
比较运算符'不完全等于'。因此,如果孩子的父母不是父母(您指定的),则评估为true
,但如果孩子的父母是父母,则评估为false
。
因此,如果c!==p
的计算结果为false,那么&&
运算符将false
作为while条件返回,而while循环则停止。 (注意,不需要一个while-body,并且需要关闭;
分号。)
所以当while循环结束时,c
要么是一个节点(而不是null
),当它找到一个父OR或它是null
时(当循环一直到最后没有找到匹配)。
因此,我们简单地return
这个事实(转换为布尔值,而不是节点):return !!c;
:!
(NOT
运算符)反转一个布尔值(true
变为false
,反之亦然)。
!c
将c
(node或null)转换为布尔值,然后才能反转该值。因此,添加第二个!
(!!c
)将此错误转换为true(这就是为什么双!!
经常被用来'将任何东西转换为boolean')。
额外: 函数的主体/有效负载是如此之小,以至于根据情况而定(例如,当它不经常使用并且在代码中只出现一次时),甚至可以省略函数(包装)并使用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()
method:
var parent = document.querySelector('.parent'),
child = document.querySelector('.child');
if (parent.contains(child)) {
// .. it's a child
}
看看Node#compareDocumentPosition。
function isDescendant(ancestor,descendant){
return ancestor.compareDocumentPosition(descendant) &
Node.DOCUMENT_POSITION_CONTAINS;
}
function isAncestor(descendant,ancestor){
return descendant.compareDocumentPosition(ancestor) &
Node.DOCUMENT_POSITION_CONTAINED_BY;
}
其他关系包括DOCUMENT_POSITION_DISCONNECTED
,DOCUMENT_POSITION_PRECEDING
和DOCUMENT_POSITION_FOLLOWING
。
IE <= 8不支持。
你可以使用contains method
var result = parent.contains(child);
或者你可以尝试使用compareDocumentPosition()
var result = nodeA.compareDocumentPosition(nodeB);
最后一个更强大:它返回一个位掩码作为结果。
试试这个:
x = document.getElementById("td35");
if (x.childElementCount > 0) {
x = document.getElementById("LastRow");
x.style.display = "block";
}
else {
x = document.getElementById("LastRow");
x.style.display = "none";
}
我遇到了一段很棒的代码来检查一个元素是否是另一个元素的子元素。我必须使用它,因为IE不支持.contains
元素方法。希望这也会对其他人有所帮助。
以下是功能:
function isChildOf(childObject, containerObject) {
var returnValue = false;
var currentObject;
if (typeof containerObject === 'string') {
containerObject = document.getElementById(containerObject);
}
if (typeof childObject === 'string') {
childObject = document.getElementById(childObject);
}
currentObject = childObject.parentNode;
while (currentObject !== undefined) {
if (currentObject === document.body) {
break;
}
if (currentObject.id == containerObject.id) {
returnValue = true;
break;
}
// Move up the hierarchy
currentObject = currentObject.parentNode;
}
return returnValue;
}
我最近遇到过这个函数,可能会: