jQuery jQuery.contains() Method

Beginner
⏱️ 9 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
DOM check

What You’ll Learn

The jQuery.contains() utility returns true when one DOM element is a descendant of another — direct child or nested deeper. This tutorial covers syntax, official document examples, nested trees, jQuery unwrap patterns, click-outside guards, and comparisons with native contains and .find().

01

Syntax

$.contains(a, b)

02

Boolean

true / false

03

Parent

Arg 1

04

Child

Arg 2

05

DOM only

Not jQuery

06

Guards

Click outside

Introduction

When you build interactive pages, you often need to know whether one element lives inside another. Dropdown menus close when you click outside them. Drag-and-drop validates that items stay within a container. Event handlers check whether the click target belongs to a panel.

jQuery provides jQuery.contains() (also written $.contains()) for exactly that: a fast boolean test between two DOM nodes. It answers “Is contained a descendant of container?” without searching the whole tree with selectors.

Understanding the jQuery.contains() Method

jQuery.contains(container, contained) returns true when contained is inside container in the DOM hierarchy — child, grandchild, or any deeper nested element.

It returns false when the nodes are the same element, siblings, unrelated branches, or when contained is actually an ancestor of container. Argument order matters: parent first, potential descendant second.

💡
Beginner Tip

Both arguments must be native DOM elements — not jQuery objects. Use $("#menu")[0] or $("#menu").get(0) to unwrap collections.

📝 Syntax

General form of jQuery.contains:

jQuery
jQuery.contains( container, contained )

// or

$.contains( container, contained )

Parameters

  • container — the DOM element that may contain the other node.
  • contained — the DOM element that may be a descendant.

Return value

  • true if contained is a descendant of container.
  • false otherwise — including reversed order and non-element nodes.

Minimal workflow

jQuery
var panel = document.getElementById("panel");

var target = event.target;



if ($.contains(panel, target)) {

  // click happened inside panel

}

⚡ Quick Reference

Relationship$.contains(container, contained)
documentElementbodytrue
bodydocumentElementfalse
Parent → direct childtrue
Parent → nested grandchildtrue
Sibling → siblingfalse
Same element twicefalse
Container → text nodefalse

📋 $.contains vs .find() vs .has() vs native

Four ways to reason about DOM relationships — pick the right tool.

$.contains
2 nodes

Boolean descendant test

.find()
selector

Search descendants

.has()
filter set

Keep parents with match

node.contains
native

Includes text nodes

Examples Gallery

Each example uses $.contains() with jQuery 3.7.1. Open DevTools or use the Try-it links to run them interactively.

📚 Getting Started

Official jQuery API examples — documentElement and body.

Example 1 — Official documentElement vs body

The canonical examples from the jQuery documentation.

jQuery
console.log(

  $.contains(document.documentElement, document.body)

); // true



console.log(

  $.contains(document.body, document.documentElement)

); // false
Try It Yourself

How It Works

<html> wraps <body>, so the first call is true. Reversing the arguments asks the wrong question — body does not contain html.

📈 Practical Patterns

Nested elements, siblings, jQuery unwrap, and click-outside guards.

Example 2 — Nested Descendants Return true

Direct children and deeply nested elements both pass.

jQuery
var box = document.getElementById("box");

var item = document.getElementById("item");

var label = document.getElementById("label");



console.log($.contains(box, item));  // true — direct child

console.log($.contains(box, label)); // true — grandchild
Try It Yourself

How It Works

contains walks the ancestor chain from contained upward. Any level of nesting counts — you do not need a separate check for grandchildren.

Example 3 — Siblings and Unrelated Nodes Return false

Elements at the same level are not descendants of each other.

jQuery
var boxA = document.getElementById("box-a");

var boxB = document.getElementById("box-b");



console.log($.contains(boxA, boxB)); // false — siblings

console.log($.contains(boxA, boxA)); // false — same node
Try It Yourself

How It Works

A node is not considered a descendant of itself. Siblings share a parent but neither contains the other — both calls correctly return false.

Example 4 — Unwrap jQuery Objects Before Calling

Pass DOM elements, not jQuery collections.

jQuery
var $menu = $("#menu");

var $link = $("#menu-link");



// Correct — unwrap with [0] or .get(0)

console.log($.contains($menu[0], $link[0])); // true



// Wrong — jQuery objects are not DOM elements

console.log($.contains($menu, $link)); // false (unexpected)
Try It Yourself

How It Works

jQuery collections are array-like objects, not elements. The API docs explicitly require DOM elements for the first argument — always unwrap before calling $.contains.

Example 5 — Click-Outside Guard for a Dropdown

Close a menu when the click target is not inside the menu element.

jQuery
var menuEl = document.getElementById("dropdown");



$(document).on("click", function (event) {

  var inside = $.contains(menuEl, event.target);

  if (!inside) {

    $("#dropdown").removeClass("open");

  }

});



// Click inside keeps open; click outside removes "open"
Try It Yourself

How It Works

event.target is the deepest element clicked. $.contains(menuEl, event.target) returns true for clicks on the menu and its children — the classic dropdown dismiss pattern.

🚀 Common Use Cases

  • Click outside to close — menus, modals, tooltips.
  • Drop zone validation — confirm dragged nodes stay in container.
  • Event target checks — ignore clicks outside a panel.
  • Plugin boundaries — verify nodes belong to widget root.
  • Focus trap helpers — test whether active element is inside dialog.
  • Editor overlays — decide if selection is within editable region.

🧠 How jQuery.contains() Walks the DOM Tree

1

Validate elements

Both arguments should be DOM element nodes — unwrap jQuery objects first.

Input
2

Start at contained

Begin from the potential descendant and walk up via parentNode.

Walk
3

Compare ancestors

If any ancestor equals container, the descendant relationship is confirmed.

Match
4

Return boolean

true when found in the chain; false at document without a match.

📝 Notes

  • Available since jQuery 1.4 — still supported in jQuery 3.7.x.
  • First argument must be a DOM element — not a jQuery object or plain object.
  • Second argument must be an element node — text/comment nodes return false.
  • Argument order is (container, contained) — reversing them changes the result.
  • Modern browsers also expose native Node.contains() — jQuery’s version is stricter on node types.
  • Related: .find(), .has(), .closest(), event.target.

Browser Support

jQuery.contains() has been part of jQuery since jQuery 1.4+. It works wherever jQuery runs — all modern browsers and legacy IE when paired with a supported jQuery build.

jQuery 1.4+

jQuery jQuery.contains()

Supported in jQuery 1.x, 2.x, and 3.x. Cross-browser descendant checks without relying on native Node.contains alone.

100% With jQuery loaded
Google Chrome All versions · Desktop & Mobile
Full support
Mozilla Firefox All versions · Desktop & Mobile
Full support
Apple Safari All versions · macOS & iOS
Full support
Microsoft Edge All versions · Chromium & Legacy
Full support
Internet Explorer IE 6+ · Legacy environments
Full support
Opera All modern versions
Full support
jQuery.contains() Universal

Bottom line: Safe in any project that already includes jQuery. In modern-only code you may use container.contains(contained) — but unwrap jQuery objects either way.

Conclusion

The jQuery.contains() utility answers a precise DOM question: is this element inside that one? It powers click-outside patterns, boundary checks, and plugin guards — with a simple boolean return.

Remember: pass native DOM elements, put the container first, and expect false for siblings, reversed order, and non-element nodes. Unwrap jQuery collections with [0] before every call.

💡 Best Practices

✅ Do

  • Unwrap jQuery objects: $.contains($a[0], $b[0])
  • Pass container first, descendant second
  • Use for click-outside and boundary validation
  • Combine with event.target in document handlers
  • Validate elements exist before calling contains

❌ Don’t

  • Pass jQuery collections directly
  • Reverse argument order accidentally
  • Expect text nodes to pass the element-only check
  • Use contains when a selector search (.find) is clearer
  • Assume a node contains itself — that returns false

Key Takeaways

Knowledge Unlocked

Five things to remember about jQuery.contains()

Test DOM descendant relationships the jQuery way.

5
Core concepts
02

Nested

true

Descendant
🚫 03

Sibling

false

Reject
📦 04

[0]

Unwrap

jQuery
👈 05

Click

Outside

Pattern

❓ Frequently Asked Questions

jQuery.contains(container, contained) returns true when contained is a descendant of container — a direct child or nested deeper in the DOM tree. It returns false when the nodes are unrelated, siblings, or when contained is not inside container.
No. Both arguments must be native DOM elements. Unwrap jQuery collections with [0], .get(0), or .get()[0] before calling $.contains(container, contained).
No. jQuery.contains() only supports element nodes for the second argument. Text and comment nodes return false even when they appear inside container visually.
Native Node.contains() accepts any Node type including text nodes. jQuery.contains() is stricter — elements only for the second argument — but works consistently across browsers jQuery supports, including older IE where jQuery added this helper.
contains() is a boolean test between two known nodes. .find() searches descendants from a jQuery collection. .has() filters a collection to elements that contain a matching descendant selector.
Use it for click-outside detection, validating that a dragged node stays inside a drop zone, ensuring event targets belong to a panel, and any logic that asks: is node A inside node B?
Did you know?

jQuery added contains in version 1.4 partly because native contains behavior varied across old browsers. The jQuery version normalizes descendant checks — but only for element nodes in the second argument, which is why clicking text inside a button can behave differently between $.contains and native Node.contains().

Continue to jQuery.data()

Attach and retrieve arbitrary data on DOM elements.

data() tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful