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

如何检查一个DOM元素是否是另一个DOM元素的子元素?有什么内置的方法吗?例如,像这样:

if (element1.hasDescendant(element2))

if (element2.hasParent(element1))

如果没有,有什么想法如何做到这一点?它还需要跨浏览器。我还应该提到,子对象可以嵌套在父对象的许多层之下。

226459 次浏览

现在有一个本地的方法来实现这一点。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;
}

我遇到了一段很棒的代码,用来检查一个元素是否是另一个元素的子元素。我必须使用这个,因为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;
}

看看节点#是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不支持。

我只需要分享“我的”。

尽管在概念上与亚萨的回答相同(受益于相同的跨浏览器兼容性,甚至是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这里


< p > < em >用法:< / em > < br > childOf(child, parent)返回布尔值true|false.

< p > < em >解释:< / em > < br > 只要while-condition计算为truewhile就会计算 && (AND)操作符返回布尔值true/false ,计算左边和右边,但只有如果左边为真(left-hand && right-hand)。< / p >

(&&)的左边是:(c=c.parentNode).
这将首先将cparentNode赋值给c,然后and运算符将计算得到的c作为一个布尔值 由于如果没有父元素,parentNode将返回null,并且null将转换为false,因此当没有更多父元素时,while循环将正确停止

(&&)的右边是:c!==p.
!==比较操作符是' exactly equal to'。因此,如果子对象的父对象不是你指定的父对象,则计算结果为true,但如果子对象的父对象为父对象,则计算结果为false.
因此如果 c!==p的值为false,然后&&操作符返回false作为while条件,while循环停止。(注意,这里不需要while-body,并且需要结束;分号。

因此,当while循环结束时,c要么是找到父节点时的节点(不是null),要么是null(当循环运行到最后没有找到匹配时)。

因此,我们简单地return事实(转换为布尔值,而不是节点):return !!c;: ! (NOT操作符)反转布尔值(true变成false,反之亦然) !cc(节点或null)转换为一个布尔值,然后才能反转该值。因此,添加第二个! (!!c)将这个假的回来转换为真(这就是为什么经常使用双!!来“将任何东西转换为布尔值”)
< p > 额外的: < br > 函数体/有效负载非常小,根据情况(比如它不经常使用,只在代码中出现一次),可以甚至省略了函数(换行),只使用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.contains,因为它现在是标准的,在所有浏览器中都可用。

https://developer.mozilla.org/en-US/docs/Web/API/Node.contains < a href = " https://developer.mozilla.org/en-US/docs/Web/API/Node.contains " > < / >

另一个没有提到的解决方案:

示例 .

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);

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

试试这个:

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";
}

TL;DR:图书馆

我建议使用类似dom-helpers的东西,它是由react团队作为常规JS库编写的。

在他们的包含实现中,你会看到一个基于节点#包含的实现和一个节点#是compareDocumentPosition的回退。

不支持非常老的浏览器,如IE <9,我觉得这是可以接受的。

这个答案包含了上面的问题,但是我建议你不要循环。

考虑使用closest('.selector')

如果元素和它的任何祖先都不匹配选择器,则返回null。或者返回找到的元素