.contents() (since jQuery 1.2) returns the direct child nodes of each matched element — including text and comment nodes. It is like .children(), but broader. Since 3.2 it also returns contents of <template> elements.
Remember
$("p").contents(); // elements + text + comments
$("p").children(); // elements only
// Official pattern — wrap non-element nodes
$("p").contents()
.filter(function () { return this.nodeType !== 1; })
.wrap("<b>");
// Same-origin iframe document
$("#frame").contents().find("a");
Select a parent, call .contents(), then filter by node type if needed.
Select the parent(s) — e.g. $("p") or $(".container").
Call .contents() (no arguments) for every direct child node.
Filter when needed: nodeType === 3 for text, !== 1 for non-elements.
Chain safe methods — .wrap(), .each(), .remove() on elements.
For iframes, use only same-origin frames, then .find() inside.
Piece
Required?
Role
Matched set
Yes
Parents whose child nodes you want
Arguments
None
.contents() takes no parameters
nodeType filter
Often
Isolate text (3), comment (8), or element (1)
Depth
—
Always exactly one level
Pseudocode
Pseudocode
call $(parents).contents()
result = empty set
for each parent in the matched set:
for each direct child node of parent:
add node to result
(element, text, or comment)
return result as a new jQuery object
optional next step:
filter by nodeType before wrap / style
Reference
Cheat Sheet
Keep these facts next to .children().
Topic
Detail
Syntax
.contents()
Since
jQuery 1.2 (<template> since 3.2)
Depth
One level only
Nodes
Elements + text + comments
vs .children()
Elements only
nodeType
1 = element, 3 = text, 8 = comment
iframe
Same-origin document access
DOM change?
No by itself — query only
Try it
Live Preview
Compare .contents() with .children(), or wrap text nodes.
Sample paragraph mixes text and a span. Text nodes appear in .contents() only.
Hello John, how are you?
Result
Ready — pick an action and click Run.
Code
jQuery Examples
Short, copy-ready snippets. Use Try It Yourself for a live editor.
Example 1 — Official Wrap Text in <b>
Wrap non-element child nodes inside a paragraph (official demo idea).
Find..find("a") selects links inside that document.
Limit. Cross-origin iframes block this access.
Edge Cases & Pitfalls
Check these when .contents() looks empty or fails to style.
methods
Most jQuery APIs need elements
Calling .css() or .addClass() on text nodes is unreliable. Filter to elements, or use methods that support text nodes (like .wrap()).
depth
One level only
Text inside a child element is not returned. Call .contents() on that child, or use .find() for element descendants.
iframe
Same-origin only
Cross-origin iframes throw a security error. Wait for load before reading .contents().
whitespace
Whitespace is a text node
Newlines and spaces between tags count as text nodes. Filter empty text if you only want visible content.
Compatibility
Browser Support
.contents() is a core jQuery traversing method since 1.2. It works in every browser that runs your loaded jQuery version. <template> contents are included since 3.2.
✓ Stable · jQuery 1.2+
jQuery .contents()
Universal across jQuery-supported browsers. iframe access still depends on same-origin policy.
1.2+jQuery since
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 for everyday use. Filter by nodeType before styling text, and keep iframe demos same-origin.
Analysis
Performance Notes
Approach
Cost
Best for
$("#box").contents()
Cheap
Local parent, few child nodes
$("p").contents() then filter
Cheap–moderate
Text-node edits across many paragraphs
$("div").contents() page-wide
Moderate
Avoid — too broad; scope first
Scope to a known parent. Prefer .children() when you only need elements — it skips text/comment work you do not need.
Remember
Key Takeaways
Role: get direct child nodes, including text and comments.
vs .children(): broader set — elements plus non-elements.
Filter: use nodeType before wrap/style on text nodes.
iframe: same-origin only; wait for load first.
One line:.contents() is one-level children plus text/comments — filter by nodeType before most jQuery actions.
Frequently Asked Questions
.contents() returns a new jQuery object with all direct child nodes of each matched element — elements, text nodes, and comments. Like .children(), it goes one level down, but it also includes non-element nodes.
.children() returns only direct child elements. .contents() also includes text and comment nodes. Use .contents() when you need text nodes; use .children() for element-only queries.
Most jQuery methods expect element nodes. Text nodes use nodeType 3, comments use 8, elements use 1. Filter after .contents() before wrapping or styling text.
Yes, when the iframe is same-origin. $('#frame').contents() returns the iframe document so you can chain .find(). Cross-origin iframes are blocked for security.
No. It only inspects direct child nodes one level down. Nested text inside a child element is not included — go into that child first, or use .find() for element descendants.
No. .contents() accepts no parameters. Filter afterward with .filter() if you need only text nodes or only elements.