Himanshu SharmaSoftware engineer
Let’s talk

jQuery · Lesson 10 of 45

Getting and setting text and HTML

Read and change element content with jQuery .text() and .html(), understand the difference, and avoid cross-site scripting when showing user input.

11 minReading and changing the pageUpdated 23 October 2026

By the end of this lessonChange the words on a page safely with .text(), use .html() only for trusted markup, and update content based on what is already there.

Two methods, two kinds of content

An element's content can be thought of in two ways:

  • its text: just the characters a reader sees;
  • its HTML: the markup, including any tags inside it.

jQuery has a method for each: .text() and .html(). Both are getters without an argument and setters with one.

html
<p id="intro">Learn <strong>jQuery</strong> today.</p>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  console.log("text:", $("#intro").text());
  console.log("html:", $("#intro").html());
</script>
result
text: Learn jQuery today.
html: Learn <strong>jQuery</strong> today.

.text() drops the tags and returns only the words. .html() returns the markup exactly as the browser holds it.

Setting text

.text(value) replaces everything inside the element with plain text:

html
<p id="status">Loading...</p>
<p id="raw"></p>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#status").text("Saved at 10:30");
  $("#raw").text("<b>Not bold</b>");
  console.log($("#raw").html());
</script>
result
&lt;b&gt;Not bold&lt;/b&gt;

The second paragraph shows the characters <b>Not bold</b> instead of bold text. jQuery escaped the angle brackets, which you can see in the logged HTML as &lt; and &gt;. This escaping is what makes .text() safe for any value, including what a visitor typed.

Setting HTML

.html(value) parses the string as markup and builds real elements:

html
<div id="card"></div>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#card").html("<h3>Desk lamp</h3><p>Price: <strong>1,200</strong></p>");
  console.log($("#card").children().length, "elements created");
  console.log($("#card strong").text());
</script>
result
2 elements created
1,200

After the call, #card contains a real h3 and p that you can select and style like any other elements.

The danger: cross-site scripting

Suppose a comment form shows the visitor's comment with .html(). A visitor types something that is not a normal comment:

html
<input id="comment" value='Nice post! <img src=x onerror="console.log(&apos;attacker code ran&apos;)">' size="60">
<button id="unsafe">Show with .html()</button>
<button id="safe">Show with .text()</button>
<div id="out"></div>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#unsafe").on("click", () => $("#out").html($("#comment").val()));
  $("#safe").on("click", () => $("#out").text($("#comment").val()));
</script>
result
attacker code ran

With .html(), the browser created an image with a broken address, and its onerror attribute ran JavaScript: that is the line in the output. On a real site, that code could read the page, change it, or send the visitor's data elsewhere. This attack is called cross-site scripting (XSS), and it is one of the most common web security bugs.

With .text(), the same input is shown harmlessly as characters.

The rule is simple: use .text() for anything that came from a user, a URL, or a server you do not fully control. Use .html() only for markup you wrote yourself. When you need to build HTML around user data, create the elements and set the user part with .text():

html
<ul id="comments"></ul>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  const name = "Ravi <script>";
  const message = "Great <b>tutorial</b>";

  const $li = $("<li>");
  $("<strong>").text(name).appendTo($li);
  $li.append(": ", document.createTextNode(message));
  $("#comments").append($li);

  console.log($li.html());
</script>
result
<strong>Ravi &lt;script&gt;</strong>: Great &lt;b&gt;tutorial&lt;/b&gt;

The structure (the strong element) is yours; the user's words go in as text, so their angle brackets are escaped.

Updating based on the current value

Both setters accept a function instead of a value. It runs once per element, receives the index and the current content, and returns the new content:

html
<ul>
  <li>apple</li>
  <li>banana</li>
  <li>cherry</li>
</ul>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("li").text(function (index, oldText) {
    return (index + 1) + ". " + oldText.toUpperCase();
  });
  console.log($("li").text());
</script>
result
1. APPLE2. BANANA3. CHERRY

This replaces a whole .each() loop with one call.

Emptying content

To clear an element, set its text to an empty string or use .empty():

javascript
$("#results").text("");
$("#results").empty();   // same effect, and clearer

.empty() removes everything inside but keeps the element itself. The lesson on removing elements covers it with .remove().

Text across several elements

Remember that .text() as a getter joins the text of all selected elements, while .html() reads only the first. If you want each element's text separately, use .map():

javascript
const names = $("li").map((i, el) => $(el).text()).get();

Common mistakes

  • Using .html() to show user input. Use .text().
  • Using .text() when you meant to add markup, and seeing tags printed on the page.
  • Expecting .html() to read every element. It reads the first.
  • Setting .html() repeatedly in a loop. Build the string or elements first and set them once; each call makes the browser parse and rebuild the content.

Exercise

Add a text input and a Preview button. When the button is clicked, show the input's value inside a <p id="preview"> so that any HTML the user types is displayed, not run.

Show one possible answer
html
<input id="msg" value="<i>hello</i>">
<button id="go">Preview</button>
<p id="preview"></p>

<script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
<script>
  $("#go").on("click", function () {
    $("#preview").text($("#msg").val());
  });
</script>

Key points

  • .text() reads or sets plain text; any HTML in the value is shown as characters, not run as markup.
  • .html() reads or sets markup; the browser parses the value and builds elements from it.
  • Never pass user input to .html(): it opens the page to cross-site scripting (XSS). Use .text() instead.
  • Both setters accept a function that receives the old value and returns the new one.

Check yourself

1. What does $("#out").text("<b>Hi</b>") show on the page?
2. Why is $("#out").html(userComment) dangerous?
3. What does $("p").html() return when there are three paragraphs?
4. What does the function in .text(function (i, old) { return old.toUpperCase(); }) receive as old?