jQuery / Method / .text() - Read or Replace Text Contents

jQuery's .text() returns a string combining text from all selected elements and their descendants. .text(value) replaces each selected element's contents with that text without interpreting HTML tags. To keep separate results for multiple elements, read each element into an array instead of using the combined getter.

Reading scope, html and val

The .text() API reads the whole selected collection, rather than only its first member. It omits markup but includes descendant text and does not automatically insert separators between elements. It is not a way to extract only what is visibly rendered.

Call Reading or writing Use
.text() Combines descendant text from the full selection Read ordinary element text
.text(value) Replaces all target contents with text Display a message literally
.html() Reads the first element's inner HTML Obtain tag structure
.val() Reads the current form-control value input, textarea, select

.html() handles markup, while .val() handles current input values. Do not try to read an input's current value with .text(). The text method can operate in XML as well as HTML documents.

Compare combined and per-element results

Save the entire code as UTF-8 in text-demo.html and open it in a browser. Internet is required for the official jQuery file 4.0.0 from its content delivery network (CDN); no package installation is needed. Reading, setting, callback prefixes, clearing, reset and the console example below were executed with 3.7.1 and 4.0.0.

The first paragraph contains Alpha and a hidden span containing Hidden; the second contains Beta. JSON.stringify() makes string boundaries and empty values explicit. perItem reads each element through .map() and converts the result to a plain array with .get().

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Read and replace text contents</title>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
  <style>
    body { font: 16px/1.6 sans-serif; max-width: 760px; margin: 24px auto; padding: 16px; }
    button, input { font: inherit; margin: 4px; max-width: 100%; }
    .item { border: 2px solid teal; padding: 16px; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <h1>Plain text from multiple elements</h1>
  <label>Value <input id="value" value="&lt;em&gt;Hello&lt;/em&gt;"></label>
  <button type="button" id="set">Set text</button>
  <button type="button" id="prefix">Prefix each item</button>
  <button type="button" id="clear">Clear text</button>
  <button type="button" id="read">Read</button>
  <button type="button" id="reset">Reset</button>
  <div id="items"><p class="item"><strong>Alpha</strong><span hidden>Hidden</span></p><p class="item">Beta</p></div>
  <pre id="result" aria-live="polite"></pre>
  <script>
    $(function () {
      const $items = $("#items > .item");
      const initial = $items.get().map(node => node.innerHTML);
      function report() {
        const combined = $items.text();
        const perItem = $items.map(function () { return $(this).text(); }).get();
        $("#result").text(`combined=${JSON.stringify(combined)}\nper item=${JSON.stringify(perItem)}\nitems=${$items.length}`);
      }
      $("#set").on("click", function () { $items.text($("#value").val()); report(); });
      $("#prefix").on("click", function () {
        $items.text(function (index, oldText) { return (index + 1) + ". " + oldText; });
        report();
      });
      $("#clear").on("click", function () { $items.text(""); report(); });
      $("#read").on("click", report);
      $("#reset").on("click", function () {
        $items.html(function (index) { return initial[index]; });
        $("#value").val("<em>Hello</em>");
        report();
      });
      report();
    });
  </script>
</body>
</html>

Initial output:

combined="AlphaHiddenBeta"
per item=["AlphaHidden","Beta"]
items=2
  1. Read produces the same result. Hidden is not visible, but appears in combined and the first array entry.
  2. Prefix each item uses the callback's index and oldText to produce 1. AlphaHidden and 2. Beta. strong and the hidden span are replaced with text.
  3. After Reset, press Set text. Both paragraphs display <em>Hello</em> literally; no em element is created.
  4. Edit Value and press Set text again. The input is read through .val(); leading and trailing spaces remain in the string.
  5. Clear text applies .text(""). combined becomes an empty string, per item contains two empty strings, and two paragraphs remain.
  6. Reset restores saved markup and the input. Repeated Prefix each item adds prefixes to the current text, so reset first when comparing the same initial conditions.

Whitespace, hidden content and lost formatting

No space is inserted between Alpha and Beta, so combined is AlphaHiddenBeta. Keep the perItem array when boundaries matter, or join that array with your own separator. Existing whitespace and line breaks in the Document Object Model (DOM), along with browser parsing differences, can affect the result.

Native textContent also handles text independently of rendered styling and differs from innerText. If hidden text must be excluded, first decide which elements belong in the result. A broad container query that ignores visibility is not equivalent to extracting exactly what a reader sees.

.text(value) does not merely append characters to existing structure. It replaces child markup, so applying it to an entire parent can remove icons, links or buttons. Limit the update to the label's own span when those children must remain.

Zero, false, empty selections and literal values

Run this complete fragment in the developer tools Console. It changes a temporary div without inserting it and cleans up afterward. Numbers and booleans become text; &amp; remains its literal character sequence rather than being interpreted as an HTML entity.

const $box = $("<div>A <span>B</span> C</div>");
console.log(`spaces=${JSON.stringify($box.text())}`);
$box.text(0);
console.log(`number=${JSON.stringify($box.text())}`);
$box.text(false);
console.log(`boolean=${JSON.stringify($box.text())}`);
$box.text("&amp;");
console.log(`entity characters=${JSON.stringify($box.text())}`);
console.log(`empty selection=${JSON.stringify($().text())}`);
$box.remove();
spaces="A B C"
number="0"
boolean="false"
entity characters="&amp;"
empty selection=""

An empty selection's .text() is an empty string. An existing but empty element can give the same result, so check .length to determine whether a target exists. Avoid treating zero or false as missing data through unconditional conversions such as value || "".

Ordinary strings passed to .text() do not execute as tags in this text-display path. Passing the result into .html() later is a separate HTML-parsing operation. Do not treat .text() as an HTML sanitizer; keep values intended as characters on a text path. For unexpected results, check scope, descendants, separators, use of .val() for form values and Console errors.