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
Fundamentals
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.
Concept
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.
Foundation
📝 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
}
Cheat Sheet
⚡ Quick Reference
Relationship
$.contains(container, contained)
documentElement → body
true
body → documentElement
false
Parent → direct child
true
Parent → nested grandchild
true
Sibling → sibling
false
Same element twice
false
Container → text node
false
Compare
📋 $.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
Hands-On
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.
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)
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"
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.
Applications
🚀 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.
Important
📝 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.
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 ChromeAll versions · Desktop & Mobile
Full support
Mozilla FirefoxAll versions · Desktop & Mobile
Full support
Apple SafariAll versions · macOS & iOS
Full support
Microsoft EdgeAll versions · Chromium & Legacy
Full support
Internet ExplorerIE 6+ · Legacy environments
Full support
OperaAll 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.
Wrap Up
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.
Use contains when a selector search (.find) is clearer
Assume a node contains itself — that returns false
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about jQuery.contains()
Test DOM descendant relationships the jQuery way.
5
Core concepts
🔗01
$.contains
2 DOM nodes
API
✅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().