A black and white photograph of a pregnant woman holding a phone in front of her stomach. The phone displays a baby ultrasound picture.

Deep manipulation of the DOM can leave elements scattered across a page, meaning that tracking down which elements are in which can be challenging. To address this, developers can use contains and hasChildNodes to determine if one node contains another.

Looking Inside

Given a div with markup and content inside it:

<div id="leftcol">
    <img src="babby.jpg" id="baby" class="blueeye">
    <p>Monday’s child is fair of face.</p>
</div>

We can check that an element with an id of baby exists inside leftcol with the following:

leftcol.contains(baby);

The response will be true when applied to the markup above: if baby was not inside leftcol, the response would be false. As such, contains can be the condition of an if statement:

if (leftcol.contains(baby)) {
    // do something
}

Note that contains is a “deep dive”; it’s not necessary for baby to be an immediate descendant of leftcol. contains would still be true if baby was inside another element that existed inside leftcol:

<div id="leftcol">
    <figure>
        <img src="babby.jpg" id="baby" class="blueeye">
        <figcaption>This is a babby</figcaption>
    </figure>
    <p>Monday’s child is fair of face.</p>
</div>

This is also true even if we identify the inner element in another way, so long as the result is a node; for example, using querySelector:

let babby = document.querySelector(".blueeye");
leftcol.contains(babby);
> true

Alternatives

contains has excellent browser support: everything, including IE5+, has it. In more modern browsers, the same results can be achieved with querySelector or querySelectorAll:

let babby = leftcol.querySelector(".blueeye");

if (babby) {
    console.log("Success")
}

Or, more directly:

if (leftcol.querySelector(".blueeye")) {
    console.log("Success");
}

Haz Babby?

If you want to know if an element contains any kind of markup, without caring what kind of elements may be inside it, you can use hasChildNodes:

if (leftcol.hasChildNodes()) {
    // #leftcol has elements inside; do something
}

One very important note is that whitespace is counted as a text node, so markup like this:

<div id="leftcol">

</div>

Would return true in response to hasChildNodes(). A safer method, one that looks for actual elements, is to check the number of children the element has:

if (leftcol.children.length > 0) {
    // leftcol has at least one element as a child
}

Alternatively:

if (leftcol.children.length) {
    // leftcol has at least one element as a child
}

Photograph by Marcos de Madariaga, used under a Creative Commons Attribution-NonCommercial-NoDerivs 2.0 Generic license

Enjoy this piece? I invite you to follow me at twitter.com/dudleystorey to learn more.