[javascript] How to check if element has any children in Javascript?

Simple question, I have an element which I am grabbing via .getElementById (). How do I check if it has any children?

This question is related to javascript dom

The answer is


A reusable isEmpty( <selector> ) function.
You can also run it toward a collection of elements (see example)

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

returns true (and exits loop) as soon one element has any kind of content beside spaces or newlines.


You could also do the following:

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

This uses the trim() method to treat empty elements which have only whitespaces (in which case hasChildNodes returns true) as being empty.

NB: The above method doesn't filter out comments. (so a comment would classify a a child)

To filter out comments as well, we could make use of the read-only Node.nodeType property where Node.COMMENT_NODE (A Comment node, such as <!-- … -->) has the constant value - 8

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

_x000D_
_x000D_
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') }
}
_x000D_
<div><span>An element</span>
<div>some text</div>
<div>     </div> <!-- whitespace -->
<div><!-- A comment --></div>
<div></div>
_x000D_
_x000D_
_x000D_


You can check if the element has child nodes element.hasChildNodes(). Beware in Mozilla this will return true if the is whitespace after the tag so you will need to verify the tag type.

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


Late but document fragment could be a node:

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

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


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

As slashnick & bobince mention, hasChildNodes() will return true for whitespace (text nodes). However, I didn't want this behaviour, and this worked for me :)

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

Edit: for the same functionality, this is a better solution:

 element.children.length > 0

children[] is a subset of childNodes[], containing elements only.

Compatibility


Try the childElementCount property:

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