【问题标题】:How to check if element has any children in Javascript?如何检查元素是否在Javascript中有任何子元素?
【发布时间】:2011-01-10 19:45:41
【问题描述】:

简单的问题,我有一个通过.getElementById () 抓取的元素。我如何检查它是否有孩子?

【问题讨论】:

    标签: javascript dom


    【解决方案1】:

    几种方法:

    if (element.firstChild) {
        // It has at least one
    }
    

    hasChildNodes() 函数:

    if (element.hasChildNodes()) {
        // It has at least one
    }
    

    childNodeslength 属性:

    if (element.childNodes.length > 0) { // Or just `if (element.childNodes.length)`
        // It has at least one
    }
    

    如果您只想了解所有现代浏览器(以及 IE8,甚至 IE6)上的子 元素(相对于文本节点、属性节点等),您可以这样做:(谢谢Florian!)

    if (element.children.length > 0) { // Or just `if (element.children.length)`
        // It has at least one element as a child
    }
    

    这依赖于 children 属性,该属性未在 DOM1DOM2 DOM3 中定义,但具有近乎普遍的支持。 (早在 2012 年 11 月,它就可以在 IE6 及更高版本以及 Chrome、Firefox 和 Opera 中运行,至少。)如果支持较旧的移动设备,请务必检查是否支持。

    如果您不需要 IE8 及更早版本的支持,您也可以这样做:

    if (element.firstElementChild) {
        // It has at least one element as a child
    }
    

    这依赖于firstElementChild。与children 一样,它也没有在DOM1-3 中定义,但与children 不同的是,它直到IE9 才添加到IE 中。这同样适用于childElementCount

    if (element.childElementCount !== 0) {
        // It has at least one element as a child
    }
    

    如果你想坚持 DOM1 中定义的东西(也许你必须支持真正晦涩难懂的浏览器),你必须做更多的工作:

    var hasChildElements, child;
    hasChildElements = false;
    for (child = element.firstChild; child; child = child.nextSibling) {
        if (child.nodeType == 1) { // 1 == Element
            hasChildElements = true;
            break;
        }
    }
    

    所有这些都是DOM1 的一部分,并且几乎得到了普遍支持。

    很容易将其包装在一个函数中,例如:

    function hasChildElement(elm) {
        var child, rv;
    
        if (elm.children) {
            // Supports `children`
            rv = elm.children.length !== 0;
        } else {
            // The hard way...
            rv = false;
            for (child = element.firstChild; !rv && child; child = child.nextSibling) {
                if (child.nodeType == 1) { // 1 == Element
                    rv = true;
                }
            }
        }
        return rv;
    }
    

    【讨论】:

    • 哦,我没有意识到 children 只是在 DOM4 中添加的。知道任何已知浏览器都支持它,我认为这几乎是 DOM0/1。
    • 我如何检查是否有任何div 具有元素div 具有特定类说xyz
    • 从未见过像for (child = element.firstChild; child; child = child.nextSibling ) 这样的循环条件,已投票。谢谢 T.J.
    • @Aaron: 当element.children.length0: firstChild 时,element.firstChild 完全有可能成为非nullfirstChild 等与 nodes 相关,包括元素、文本节点、注释注释等; children 纯粹是 element 子元素的列表。在现代浏览器上,您可以改用firstElementChild
    • @TysonGibby - 哇,不知道childElementCount。查看它,请注意 childElementCount 只计算子 元素,而不是所有子节点(就像 children.length 一样)。也许您正试图使用​​firstChild 或类似名称“检测”,并且该元素包含文本节点或注释节点(但不包含元素)。 :-)
    【解决方案2】:

    正如 slashnick 和 bobince 提到的,hasChildNodes() 将为空格(文本节点)返回 true。但是,我不想要这种行为,这对我有用:)

    element.getElementsByTagName('*').length > 0
    

    编辑:对于相同的功能,这是一个更好的解决方案:

     element.children.length > 0
    

    children[]childNodes[] 的子集,仅包含元素。

    Compatibility

    【讨论】:

      【解决方案3】:

      您还可以执行以下操作:

      if (element.innerHTML.trim() !== '') {
          // It has at least one
      } 
      

      这使用 trim() 方法将只有空格的空元素(在这种情况下hasChildNodes 返回 true)视为空。

      注意:上述方法没有过滤掉cmets。 (所以评论会将孩子归类)

      为了过滤掉 cmets,我们可以使用只读的Node.nodeType 属性,其中Node.COMMENT_NODE(评论节点,例如<!-- … -->)具有常量值 - 8

      if (element.firstChild?.nodeType !== 8 && element.innerHTML.trim() !== '' {
         // It has at least one
      }
      

      let divs = document.querySelectorAll('div');
      for(element of divs) {
        if (element.firstChild?.nodeType !== 8 && element.innerHTML.trim() !== '') {
         console.log('has children')
        } else { console.log('no children') }
      }
      <div><span>An element</span>
      <div>some text</div>
      <div>     </div> <!-- whitespace -->
      <div><!-- A comment --></div>
      <div></div>

      【讨论】:

      • HTML cmets 的行为如何?
      • @VictorZamanian 好点! - 我为此添加了代码...当然,如果不打算将文本节点和 cmets 包含为子节点,那么element.firstElementChild 可能是最简单的方法:)
      【解决方案4】:

      您可以检查元素是否有子节点element.hasChildNodes()。请注意,在 Mozilla 中,如果标签后面是空格,这将返回 true,因此您需要验证标签类型。

      https://developer.mozilla.org/En/DOM/Node.hasChildNodes

      【讨论】:

      • 不仅在 Mozilla 中。这是正确的行为;是 IE 弄错了。
      【解决方案5】:

      试试childElementCount property

      if ( element.childElementCount !== 0 ){
            alert('i have children');
      } else {
            alert('no kids here');
      }
      

      【讨论】:

        【解决方案6】:

        迟到但文档片段可能是一个节点:

        function hasChild(el){
            var child = el && el.firstChild;
            while (child) {
                if (child.nodeType === 1 || child.nodeType === 11) {
                    return true;
                }
                child = child.nextSibling;
            }
            return false;
        }
        // or
        function hasChild(el){
            for (var i = 0; el && el.childNodes[i]; i++) {
                if (el.childNodes[i].nodeType === 1 || el.childNodes[i].nodeType === 11) {
                    return true;
                }
            }
            return false;
        }
        

        见:
        https://github.com/k-gun/so/blob/master/so.dom.js#L42
        https://github.com/k-gun/so/blob/master/so.dom.js#L741

        【讨论】:

          【解决方案7】:

          一个可重用的isEmpty( &lt;selector&gt; ) 函数。
          您也可以将其运行到元素集合(参见示例)

          const isEmpty = sel =>
              ![... document.querySelectorAll(sel)].some(el => el.innerHTML.trim() !== "");
          
          console.log(
            isEmpty("#one"), // false
            isEmpty("#two"), // true
            isEmpty(".foo"), // false
            isEmpty(".bar")  // true
          );
          <div id="one">
           foo
          </div>
          
          <div id="two">
           
          </div>
          
          <div class="foo"></div>
          <div class="foo"><p>foo</p></div>
          <div class="foo"></div>
          
          <div class="bar"></div>
          <div class="bar"></div>
          <div class="bar"></div>

          只要一个元素除了空格或换行符之外还有任何类型的内容,就会返回true(并退出循环)。

          【讨论】:

            【解决方案8】:
            <script type="text/javascript">
            
            function uwtPBSTree_NodeChecked(treeId, nodeId, bChecked) 
            {
                //debugger;
                var selectedNode = igtree_getNodeById(nodeId);
                var ParentNodes = selectedNode.getChildNodes();
            
                var length = ParentNodes.length;
            
                if (bChecked) 
                {
            /*                if (length != 0) {
                                for (i = 0; i < length; i++) {
                                    ParentNodes[i].setChecked(true);
                                }
                }*/
                }
                else 
                {
                    if (length != 0) 
                    {
                        for (i = 0; i < length; i++) 
                        {
                            ParentNodes[i].setChecked(false);
                        }
                    }
                }
            }
            </script>
            
            <ignav:UltraWebTree ID="uwtPBSTree" runat="server"..........>
            <ClientSideEvents NodeChecked="uwtPBSTree_NodeChecked"></ClientSideEvents>
            </ignav:UltraWebTree>
            

            【讨论】:

            • 请不要只提供纯代码解决方案。另外,你为什么要注释掉那里的代码?
            • 投反对票:这段代码晦涩难懂,部分代码是不必要的,没有 cmets 或解释,看起来像复制/过去。 XML 部分也与这里无关。
            • 这是什么疯子?
            猜你喜欢
            • 2022-12-16
            • 2020-02-21
            • 1970-01-01
            • 2014-11-15
            • 1970-01-01
            • 2011-04-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多