如果一个元素被包含在另一个元素中,如何检查Javascript

如何检查一个DOM元素是否是另一个DOM元素的子元素? 有没有内置的方法呢? 例如,像这样的东西:

if (element1.hasDescendant(element2)) 

要么

 if (element2.hasParent(element1)) 

如果不是那么任何想法如何做到这一点? 它还需要跨浏览器。 我还应该提到,孩子可以嵌套在父母的许多层次上。

使用parentNode属性应该可以工作。 从跨浏览器的angular度来看,这也是非常安全的。 如果知道这个关系是一个深层次的话,你可以简单地检查一下:

 if (element2.parentNode == element1) { ... } 

如果孩子可以在父母的任意深处嵌套,则可以使用类似于以下的函数来testing关系:

 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的答案相同(从相同的跨浏览器兼容性(即使是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} 

和jsfiddle在这里 。


用法:
childOf(child, parent)返回布尔值true | false

说明:
while只要条件评估为true进行评估。
&& (AND)运算符评估左侧和右侧返回此布尔值true / false,但仅在左侧为true left-hand && right-hand时才返回。

&& )的左边是(c=c.parentNode)
这将首先将cparentNode赋值给c ,然后AND运算符将计算结果c作为布尔值。
由于parentNode在没有父节点的情况下返回null ,并且null被转换为false ,所以当没有父节点时,while循环将正确停止。

&& )的右边是: c!==p
!==比较运算符“ 完全等于”。 所以如果孩子的父母不是父母(你指定),它的计算结果为true ,但如果孩子的父母父母,则计算结果为false
因此, 如果 c!==p计算结果为false,那么&&运算符将返回false作为while-condition和while循环停止。 (注意,不需要while-body和closing ;分号是必需的。)

所以当while循环结束的时候, c是一个节点(不是null ),当它find一个父节点或者它是null (当循环运行到最后而没有find匹配的时候)。

因此,我们简单地return这个事实(转换为布尔值,而不是节点): return !!c;!NOT运算符)颠倒布尔值( true变为false ,反之亦然)。
!cc (节点或null)转换为布尔值,然后才可以反转该值。 所以再加一个!!!c )将这个虚假的返回值转换为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 } 

看看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_DISCONNECTEDDOCUMENT_POSITION_PRECEDINGDOCUMENT_POSITION_FOLLOWING

IE不支持<= 8。

另一个没有提到的解决scheme是:

示例在这里

 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 } 

您可以使用包含方法

var result = parent.contains(child);

或者你可以尝试使用compareDocumentPosition()

var result = nodeA.compareDocumentPosition(nodeB);

最后一个更强大:它返回一个位掩码结果。

我在网上看到一段精彩的代码,检查一个元素是否是其他元素的子元素。 我不得不使用这个,因为IE不支持java脚本的“.contains”。 希望这也能帮助其他人。

以下是function: –

 function isChildOf(ChildObject,ContainerObject) { var retval=false; var curobj; if(typeof(ContainerObject)=="string") { ContainerObject=document.getElementById(ContainerObject); } if(typeof(ChildObject)=="string") { ChildObject=document.getElementById(ChildObject); } curobj=ChildObject.parentNode; while(curobj!=undefined) { if(curobj==document.body) { break; } if(curobj.id==ContainerObject.id) { retval =true; break; } curobj=curobj.parentNode;//move up the hierarchy } return retval; }