How to Use jQuery .contents() with Text Nodes

The jQuery .contents() method is a specialized traversal tool that retrieves all immediate children of matching elements, including text and comment nodes. Unlike typical methods like .children()—which only detect HTML element nodes—.contents() allows developers to isolate, modify, wrap, or remove raw, un-tagged text nodes inside container elements.

Why Standard Selectors Fail on Text Nodes

Standard jQuery selectors such as .find() or .children() traverse the DOM tree looking solely for HTML element nodes (Node type 1). Raw text inside a container that is not wrapped in a tag (like <span> or <p>) is a text node (Node type 3). Because CSS selectors cannot target text nodes directly, standard traversing fails to catch them.

Finding and Filtering Text Nodes

To interact with text nodes, invoke .contents() on the parent element, then use .filter() to isolate nodes with a nodeType of 3.

// HTML: <div id="container">Some text <span>A tag</span> More text</div>

var textNodes = $("#container").contents().filter(function() {
  return this.nodeType === 3;
});

The resulting jQuery collection contains only the individual text nodes of that element.

Reading and Modifying Text Content

Once the text nodes are isolated, you can read or update their content by accessing the native JavaScript nodeValue property:

// Reading the text of the first text node
var firstText = textNodes.first()[0].nodeValue.trim();

// Changing the content of all text nodes inside the container
textNodes.each(function() {
  this.nodeValue = this.nodeValue.replace("More text", "Updated text");
});

Wrapping Text Nodes in HTML Tags

A common use case for .contents() is converting bare text nodes into full HTML elements so standard CSS styles or jQuery events can be applied. This is achieved using .wrap():

// Wraps every text node inside #container in a <span> tag
$("#container").contents().filter(function() {
  return this.nodeType === 3 && $.trim(this.nodeValue) !== "";
}).wrap('<span class="highlight"></span>');

Checking $.trim(this.nodeValue) !== "" ensures that whitespace and line breaks are not wrapped as empty elements.

Removing Text Nodes

To delete loose text nodes from a parent while preserving any child HTML elements, apply .remove() to the filtered collection:

$("#container").contents().filter(function() {
  return this.nodeType === 3;
}).remove();

Executing this leaves only the HTML element children (such as <span> or <strong>) intact within the parent container.