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

时间:2010-02-10 06:55:06

标签: javascript dom

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

if (element1.hasDescendant(element2)) 

if (element2.hasParent(element1)) 

如果没有那么任何想法怎么做?它还需要跨浏览器。我还应该提到,孩子可以嵌套在父母以下的许多级别。

10 个答案:

答案 0 :(得分:287)

您应该使用Node.contains,因为它现在已成为所有浏览器的标准版本。

https://developer.mozilla.org/en-US/docs/Web/API/Node.contains

答案 1 :(得分:172)

使用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;
}

答案 2 :(得分:39)

我只需要分享'我的'。

虽然在概念上与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}

jsfiddle here


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

<强> 说明:
只要while条件评估为whiletrue就会进行评估 在评估左侧和右侧之后,&&(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),当它找到一个父节点或它是null时(当循环一直到结束时)没有找到匹配。)

因此,我们只需return该事实(转换为布尔值,而不是节点):return !!c;!NOT运算符)反转布尔值(true变为false,反之亦然 !cc(node或null)转换为布尔值,然后才能反转该值。因此,添加第二个!!!c)会将此假返回转换为true(这就是为什么经常使用双!!'将任何内容转换为布尔值' )。


<强>附加
函数的主体/有效负载非常小,根据具体情况而定(例如,当它不经常使用并且在代码中只出现一次时),一个甚至可以省略函数(包装)并只使用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
}

答案 3 :(得分:23)

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

Example Here

var parent = document.querySelector('.parent');

if (parent.querySelector('.child') !== null) {
    // .. it's a child
}

元素是否是直接的孩子并不重要,它可以在任何深度工作。


或者,使用.contains() method

Example Here

var parent = document.querySelector('.parent'),
    child = document.querySelector('.child');

if (parent.contains(child)) {
    // .. it's a child
}

答案 4 :(得分:18)

看看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&lt; = 8。

不支持

答案 5 :(得分:10)

您可以使用contains method

var result = parent.contains(child);

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

var result = nodeA.compareDocumentPosition(nodeB);

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

答案 6 :(得分:1)

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

答案 7 :(得分:1)

尝试这个:

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

答案 8 :(得分:0)

TL;DR:图书馆

我建议使用诸如 dom-helpers 之类的东西,由 React 团队编写作为常规 JS 库。

在他们的 contains implementation 中,您将看到基于 Node#contains 的实现和 Node#compareDocumentPosition 回退。

支持非常旧的浏览器,例如不会给出 IE <9,我认为这是可以接受的。

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

答案 9 :(得分:-2)

我最近遇到了可能执行此功能的功能

Node.compareDocumentPosition()