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

AJ.*_*AJ. 182 javascript dom

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

if (element1.hasDescendant(element2)) 
Run Code Online (Sandbox Code Playgroud)

要么

if (element2.hasParent(element1)) 
Run Code Online (Sandbox Code Playgroud)

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

Bri*_*lma 326

您应该使用Node.contains,因为它现在是标准的并且在所有浏览器中都可用.

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

  • 它是否也支持移动浏览器?mdn文档有Android,Safari,IE和Opera的问号. (6认同)
  • 这是更好的答案 (5认同)
  • 您至少可以添加一个示例 (3认同)
  • 这是很好的答案,但例子真的很好:`varparent = document.getElementById('menu'); var allElements = document.getElementsByTagName('a'); if (parent.contains(allElements[i]) {alert('链接在meni内'); }` (2认同)

Asa*_*aph 196

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

if (element2.parentNode == element1) { ... }
Run Code Online (Sandbox Code Playgroud)

如果孩子可以在父母内部任意深度嵌套,你可以使用类似于以下的函数来测试关系:

function isDescendant(parent, child) {
     var node = child.parentNode;
     while (node != null) {
         if (node == parent) {
             return true;
         }
         node = node.parentNode;
     }
     return false;
}
Run Code Online (Sandbox Code Playgroud)

  • 如果现在有人来这里,你可能会使用Node.contains(https://developer.mozilla.org/en-US/docs/DOM/Node.contains),这是现代浏览器中的本机功能. (214认同)
  • @Asaph你能否更新你的答案,包括新的`Node.contains`?:) (3认同)
  • @JohnCarrell 有 `Node.contains`(虽然没有 caniuse 页面) (2认同)

Git*_*LAB 43

我只需要分享'我的'.

虽然概念一样亚萨的答案(受益于相同的跨浏览器的兼容性,甚至IE6),这是一个很多更小,非常适合对尺寸为溢价和/或当它不需要经常.

function childOf(/*child node*/c, /*parent node*/p){ //returns boolean
  while((c=c.parentNode)&&c!==p); 
  return !!c; 
}
Run Code Online (Sandbox Code Playgroud)

..或作为一个班轮(只有64个字符!):

function childOf(c,p){while((c=c.parentNode)&&c!==p);return !!c}
Run Code Online (Sandbox Code Playgroud)

jsfiddle在这里.


用法:
childOf(child, parent)返回booleantrue| false.

说明:
while只要while条件求值为,就进行求值true.评估左侧和右侧之后
,&&(AND)运算符返回此布尔值true/false,但前提是左侧是true(). left-hand && right-hand

左侧(的&&)是:(c=c.parentNode).
这将首先分配parentNodecc,然后与运营商将评价所形成的c一个布尔值.
因为如果没有父项并且被转换为parentNode返回,null则当没有父项时,while循环将正确停止.nullfalse

右边(的&&)是:c!==p.
!==比较操作符是" 完全等于".因此,如果孩子的父母不是父母(您指定的),则评估为true,但如果孩子的父母父母,则评估为false.
因此,如果 c!==p求值为false,则&&运算符将false作为while条件返回,而while循环将停止.(注意,不需要while-body,需要使用结束;分号.)

因此,当while循环结束时,c它是一个节点(不是null),当它找到一个父OR时它null(当循环一直到最后而没有找到匹配).

因此,我们简单地return这一事实(换算为布尔值,该节点的代替)其中:return !!c;:所述!(NOT操作者)反转的布尔值(truefalse,反之亦然).
!c在转换c该值之前,将(node或null)转换为布尔值.因此,添加second !(!!c)会将此false转换 true(这就是为什么double !!通常用于'将任何内容转换为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
}
Run Code Online (Sandbox Code Playgroud)

代替:

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
}
Run Code Online (Sandbox Code Playgroud)

  • @SolomonUcko:严格相等比较(!``==)可以通过使其清楚,它可以跳过类型检查和,将发生在松散相等比较可选的隐式转换的步骤的编译器,从而提高了速度提高的速度(由更准确地描述我们想要发生的事情,这对程序员也是有益的).我似乎还记得,当我写这篇文章时,只是松散的比较(`!=`)要么非常容易出错,要么在某些旧的浏览器中根本不起作用(我怀疑它是在IE6中,但我忘记了). (4认同)
  • 优秀的答案,非常有帮助. (2认同)

Jos*_*ier 24

另一个未提及的解决方案:

这里的例子

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

if (parent.querySelector('.child') !== null) {
    // .. it's a child
}
Run Code Online (Sandbox Code Playgroud)

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


或者,使用以下.contains()方法:

这里的例子

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

if (parent.contains(child)) {
    // .. it's a child
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为这是最优雅的解决方案. (5认同)

小智 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;
}
Run Code Online (Sandbox Code Playgroud)

其他关系包括DOCUMENT_POSITION_DISCONNECTED,DOCUMENT_POSITION_PRECEDING,和DOCUMENT_POSITION_FOLLOWING.

IE <= 8不支持.


小智 14

您可以使用contains方法

var result = parent.contains(child);

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

var result = nodeA.compareDocumentPosition(nodeB);

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