The .contents() traversing method collects all direct child nodes of each matched element — elements, text, and comments — one level down the DOM tree. This tutorial follows the official jQuery text-wrapping demos, paragraph conversion pattern, iframe document access, and compares .contents() with .children().
01
Syntax
.contents()
02
One level
Direct only
03
Text nodes
Included
04
nodeType
Filter nodes
05
Iframes
Same origin
06
Since 1.2
Core API
Fundamentals
Introduction
A <div> might hold a paragraph element, raw text, line breaks, and even HTML comments — all as separate DOM nodes. When you call .children(), jQuery returns only the element tags and skips the text in between. To work with every direct child node, including text and comments, use .contents().
Available since jQuery 1.2, .contents() takes no arguments and travels exactly one level down — the same depth as .children() — but returns a richer set of nodes. It is especially useful for wrapping loose text, cleaning up mixed content, or reaching inside a same-origin iframe.
Concept
Understanding the .contents() Method
Given a jQuery object representing one or more DOM elements, .contents() reads the childNodes of each element and returns them as a new jQuery collection. Element nodes, text nodes, and comment nodes are all included. Since jQuery 3.2, contents of <template> elements are returned as well.
Important caveat from the jQuery docs: most jQuery methods do not support text or comment nodes — only a few (like .wrap(), .replaceWith(), and .filter()) work on them. Always filter by nodeType before chaining operations that expect elements.
💡
Beginner Tip
nodeType === 1 means element, nodeType === 3 means text, and nodeType === 8 means comment. Filter after .contents() to target the node kind you need.
Foundation
📝 Syntax
General form of .contents:
jQuery
.contents()
Parameters
None — .contents() does not accept any arguments.
Return value
A new jQuery object containing all direct child nodes (elements, text, comments) of each matched element.
Text nodes inside p → wrapped in <b>
Element children (if any) → unchanged
How It Works
.contents() returns text nodes that .children() would miss. Filtering nodeType !== 1 keeps text and comments, excluding element tags. .wrap("<b>") wraps each text node individually.
Example 2 — Official Demo: Convert Line-Break Text into Paragraphs
Turn a blob of text separated by <br> tags into well-formed paragraphs — the main jQuery API documentation pattern.
Three text chunks → each wrapped in <p>
<br> separators → removed
How It Works
Text nodes (nodeType === 3) get wrapped in paragraphs. After .end() returns to the full contents set, element br nodes are filtered and removed — cleaning up the old separators.
📈 Practical Patterns
Compare with .children(), inspect node types, and reach into iframes.
Example 3 — .contents() vs .children() on the Same Element
A div with mixed text and element children returns different counts depending on which method you use.
jQuery
var $box = $( "#mixed" );
console.log( "contents:", $box.contents().length ); // elements + text
console.log( "children:", $box.children().length ); // elements only
contents: 5 (text + span + text + p + text)
children: 2 (span and p only)
How It Works
Whitespace text nodes between elements count toward .contents() but are invisible to .children(). This is the core difference between the two one-level methods.
Example 4 — Inspect and Label Each Child Node Type
Loop through .contents() results and report whether each node is an element, text, or comment.
All <a> elements inside same-origin iframe → #BADA55 background
Cross-origin iframe → security error, no access
How It Works
On an iframe element, .contents() returns the iframe’s document object. Chain .find("a") to query inside it. This only works when the iframe is same-origin — cross-origin pages block script access.
Applications
🚀 Common Use Cases
Wrap loose text — bold or paragraph-wrap text nodes that sit beside elements.
Clean mixed markup — remove br separators after converting text blocks to paragraphs.
Whitespace inspection — detect unexpected text nodes causing layout gaps.
For element-only direct children, .children() is simpler and more predictable.
Compatibility
Browser Support
.contents() has been part of jQuery since 1.2+. It relies on standard DOM childNodes traversal and works wherever jQuery runs.
✓ jQuery 1.2+
jQuery .contents()
Supported in jQuery 1.x, 2.x, and 3.x across all modern browsers and IE with supported jQuery builds. Iframe document access follows same-origin browser rules.
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
.contents()Universal
Bottom line: Safe in any jQuery project. Use .contents() for text nodes and iframe documents; use .children() for element-only queries.
Wrap Up
Conclusion
The jQuery .contents() method selects all direct child nodes — elements, text, and comments — one level down from each matched parent. It is the right tool when raw text nodes matter or when you need to reach inside a same-origin iframe.
Remember the official paragraph conversion pattern: filter text nodes with nodeType === 3, wrap them, then clean up br elements. When you only need element tags, .children() is the simpler choice.
Filter by nodeType before wrapping or styling text nodes
Use .contents() for iframe same-origin document access
Prefer .children() when text nodes are irrelevant
Check the jQuery docs before chaining methods on text nodes
Use .end() to return to the full contents set after filtering
❌ Don’t
Call .css() or .addClass() directly on text nodes
Expect .contents() to reach nested text inside child elements
Access cross-origin iframe documents — browsers block it
Confuse .contents() with .html() — different purpose
Assume whitespace text nodes are harmless — they can affect layout
Summary
Key Takeaways
Knowledge Unlocked
Five things to remember about .contents()
All direct child nodes, one level down.
5
Core concepts
🖼01
.contents()
All nodes
API
T02
Text nodes
Included
Type 3
103
One level
Direct only
Depth
🔍04
nodeType
Filter first
Pattern
🔗05
Iframe
Same origin
Extra
❓ Frequently Asked Questions
.contents() returns a new jQuery object containing all direct child nodes of each matched element — element nodes, text nodes, and comment nodes. It travels one DOM level down, like .children(), but includes non-element nodes that .children() skips.
.children() returns only direct child element nodes (tags like p, span, li). .contents() returns every direct child node — including raw text and comments. Both travel exactly one level down. Use .contents() when you need to read or manipulate text nodes; use .children() for element-only queries.
Most jQuery methods expect element nodes. Text nodes use nodeType 3, comment nodes use 8, and elements use 1. After .contents(), filter with .filter(function(){ return this.nodeType === 3; }) to isolate text, or nodeType !== 1 to exclude elements before wrapping or styling.
Yes, when the iframe is same-origin with the main page. $('#myFrame').contents() returns the iframe's document object, and you can chain .find('a') or other methods to work inside it. Cross-origin iframes block access for security.
No. Like .children(), .contents() only inspects direct child nodes one level down. Nested text or elements inside a child element are not included — use .find() for deeper searches on element nodes.
No by itself — it only queries child nodes. However, you often chain methods like .wrap(), .remove(), or .replaceWith() after filtering .contents() results, which do modify the DOM.
Did you know?
The jQuery API’s paragraph conversion recipe is a classic DOM-normalization technique: legacy CMS output often mixes raw text and <br> tags inside a single container. .contents() exposes those hidden text nodes so you can wrap them in semantic <p> tags — something .children() alone cannot do because it never sees the text.