Explain Codes LogoExplain Codes Logo

How to check in JavaScript if one element is contained within another

javascript
dom-tree
javascript-queries
performance-optimization
Anton ShumikhinbyAnton Shumikhin·Jan 8, 2025
TLDR
// Direct relationship? Then .contains() is your friend. var isContained = document.getElementById('parent').contains(document.getElementById('child'));

Here, isContained is true if child is directly or indirectly nested inside parent, false otherwise.

Less obvious scenarios

Sometimes, your elements don't have a direct parent-child relationship. In such cases, you may traverse up the DOM tree:

// Fortnite with parent nodes until we hit the ground function isDescendant(parent, child) { var node = child.parentNode; while (node !== null) { if (node === parent) { return true; // You've found me. Bravo! } node = node.parentNode; // Try again } return false; // Made it to the top without finding parent. Sad. 😔 }

This function is handy when child could be deeply nested within parent.

Alternative containment checks

The querySelector introduces another way to hunt down elements:

// .querySelector() to the rescue! var isContained = parent.querySelector('.child') !== null; // Does '.child' exist in 'parent'?

It returns true if any .child is found inside parent, at any depth. Even Nemo's deep.

Digging deeper

Need more details about the relationship between two nodes? compareDocumentPosition got ya:

// Doctor Strange's level of Node analysis var position = parent.compareDocumentPosition(child); var isContained = !!(position & Node.DOCUMENT_POSITION_CONTAINED_BY); // Am I inside this?

isContained is true if child is inside parent, and it uses bitwise operations for a more granular check. Fancy enough?

Consider inconsistent browser behavior

Despite contains() being fairly broadly supported, be aware of different browser behaviors. Using polyfills can help iron out any inconsistencies.

Consider performance

contains() is fast but if dug deep in a large DOM or calling frequently, saving the result for future use can optimize performance.

Error prevention

Do validate inputs to avoid walking into errors like TypeError: Cannot read property 'contains' of null.

Tailored solutions

Every project differs. Whether it's checking for multiple elements or complex conditions, consider glueing contains() with other query methods or logic.