textContent, classList, attributes & dataset

Change content safely

Lesson 2 of 20 · 11 min · Module 1: The page is a tree

Pages show text that comes from people: names, comments, bios. Inserting it the wrong way lets anyone inject their own HTML or scripts into your page. The safe tools are simple, and they are also the ones you need for classes and attributes.

Start this lesson →

Free. No installation: you write and run the code in your browser, and it is checked automatically.

By the end, you’ll be able to…

  • Insert user text safely with textContent
  • Change classes with classList
  • Set attributes and data-* values

The idea

textContent always inserts plain text, so <b> appears literally instead of turning bold. innerHTML parses HTML and must never receive text from users. classList.add, remove and toggle change classes, setAttribute sets any attribute, and dataset reads and writes data-* attributes.

const card = document.querySelector('.card');
card.classList.add('is-featured');
card.dataset.level = 'beginner';   // data-level="beginner"
card.querySelector('a').setAttribute('href', '/courses/css');

01Why innerHTML is dangerous

If a user writes <img src=x onerror=…> as their name and you insert it with innerHTML, the browser creates that element and runs its code for every visitor. This attack is called cross-site scripting, and textContent prevents it completely.

bio.innerHTML = '<b>Hi</b>';   // bold text: HTML is parsed
bio.textContent = '<b>Hi</b>'; // shows the characters <b>Hi</b>

02Classes describe state

Instead of setting colours from JavaScript, add or remove a class and let CSS decide how it looks. classList.toggle(name, condition) adds the class when the condition is true and removes it otherwise.

03Attributes and data-*

Most attributes have a matching property, such as img.alt or a.href. setAttribute works for every attribute. dataset maps data-plan to dataset.plan, which is handy for storing small pieces of information on elements.

Your turn

Fill the profile card from the user object: put user.name in #name and user.bio in #bio as plain text (the bio contains HTML that must not be interpreted); set the photo’s alt to Photo of followed by the name; add the class is-online to .status when user.online is true; set data-plan on .card to user.plan; and point #profile-link to /u/ followed by user.username.

What the checks look for

  • The name is shown
  • The bio appears as plain text, not as HTML
  • The photo has a meaningful alt text
  • Online users get the is-online class
  • The card stores the plan in data-plan
  • The profile link points to /u/ana
Try it in the editor →

Take this with you

Text goes in with textContent; looks change with classes.

Go a little further

Show a different badge for each plan by adding a class such as plan-pro, and style it in CSS.

Learn JavaScript in the Browser for free

20 short lessons with real code and instant checks.

See the whole course →