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
A reusable isEmpty( <selector> )
function.
You can also run it toward a collection of elements (see example)
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_
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
}
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_
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.
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.
Try the childElementCount property:
if ( element.childElementCount !== 0 ){
alert('i have children');
} else {
alert('no kids here');
}
Source: Stackoverflow.com