Docs

17.2-Modifying-the-DOM

10.2 Modifying the DOM

šŸ“š Learning Objectives

By the end of this section, you will:

  • •Modify element content using innerHTML, textContent, and innerText
  • •Work with element attributes (get, set, remove)
  • •Manipulate CSS classes and inline styles
  • •Understand the differences between content properties
  • •Work with data attributes

šŸ“– Table of Contents

  1. •Modifying Content
  2. •Working with Attributes
  3. •CSS Class Manipulation
  4. •Inline Styles
  5. •Data Attributes
  6. •Comparison Tables

Modifying Content

Content Properties Overview

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                        <div id="box">                           │
│                     Hello <strong>World</strong>                │
│                        </div>                                   │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                                 │
│  innerHTML:     "Hello <strong>World</strong>"                  │
│                 ↳ Returns/sets HTML markup                      │
│                                                                 │
│  textContent:   "Hello World"                                   │
│                 ↳ Returns/sets all text (including hidden)      │
│                                                                 │
│  innerText:     "Hello World"                                   │
│                 ↳ Returns/sets visible text only                │
│                                                                 │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

innerHTML

const element = document.getElementById('container');

// Get HTML content
console.log(element.innerHTML);

// Set HTML content (parses HTML tags)
element.innerHTML = '<p>New <em>paragraph</em></p>';

// Append HTML content
element.innerHTML += '<span>More content</span>';

// Clear content
element.innerHTML = '';

āš ļø Security Warning: Never use innerHTML with user input!

// DANGEROUS - XSS vulnerability
element.innerHTML = userInput; // āŒ Never do this!

// SAFE - use textContent for user input
element.textContent = userInput; // āœ“ Safe

textContent

const element = document.getElementById('title');

// Get text content (including hidden text)
console.log(element.textContent);

// Set text content (escapes HTML, no parsing)
element.textContent = '<p>This shows as plain text</p>';

// Result: literally displays "<p>This shows as plain text</p>"

innerText

const element = document.getElementById('content');

// Get visible text only (respects CSS)
console.log(element.innerText);

// Set visible text
element.innerText = 'New visible text';

Difference Visual

HTML:
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ <div id="example">                               │
│   Visible text                                   │
│   <span style="display: none">Hidden text</span> │
│   <script>// script content</script>             │
│ </div>                                           │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Properties Return:
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ innerHTML:   "Visible text<span style=..."       │
│              (Full HTML including tags)          │
│                                                  │
│ textContent: "Visible text Hidden text           │
│              // script content"                  │
│              (ALL text, including hidden)        │
│                                                  │
│ innerText:   "Visible text"                      │
│              (Only rendered/visible text)        │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Working with Attributes

Attribute Methods

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                    Attribute Methods                            │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                                 │
│  element.getAttribute("name")      → Get attribute value        │
│  element.setAttribute("name", val) → Set attribute value        │
│  element.removeAttribute("name")   → Remove attribute           │
│  element.hasAttribute("name")      → Check if exists (boolean)  │
│                                                                 │
│  element.attributes                → All attributes (NamedNodeMap)
│                                                                 │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Getting Attributes

const link = document.getElementById('myLink');

// Get attribute value
const href = link.getAttribute('href');
const target = link.getAttribute('target');

// Check if attribute exists
if (link.hasAttribute('disabled')) {
  console.log('Link is disabled');
}

// Get all attributes
const attrs = link.attributes;
for (const attr of attrs) {
  console.log(`${attr.name}: ${attr.value}`);
}

Setting Attributes

const img = document.getElementById('myImage');

// Set single attribute
img.setAttribute('src', 'new-image.jpg');
img.setAttribute('alt', 'Description of image');

// Set multiple attributes
const attributes = {
  src: 'photo.jpg',
  alt: 'A beautiful photo',
  width: '300',
  height: '200',
};

Object.entries(attributes).forEach(([name, value]) => {
  img.setAttribute(name, value);
});

Removing Attributes

const button = document.getElementById('submitBtn');

// Remove single attribute
button.removeAttribute('disabled');
button.removeAttribute('aria-hidden');

// Toggle attribute presence
function toggleDisabled(element) {
  if (element.hasAttribute('disabled')) {
    element.removeAttribute('disabled');
  } else {
    element.setAttribute('disabled', '');
  }
}

Direct Property Access vs getAttribute

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│        Property Access vs getAttribute                           │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                                  │
│  <a href="/page" id="link">Click</a>                            │
│                                                                  │
│  link.href                                                       │
│  → "https://example.com/page"   (Full resolved URL)              │
│                                                                  │
│  link.getAttribute("href")                                       │
│  → "/page"                      (Exact attribute value)          │
│                                                                  │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                                  │
│  Use PROPERTY for:          Use getAttribute for:                │
│  • Boolean values           • Custom attributes                  │
│  • Computed values          • Exact HTML value                   │
│  • Standard properties      • data-* attributes (or dataset)     │
│                                                                  │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

CSS Class Manipulation

classList API

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                      classList Methods                           │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                                  │
│  element.classList.add("class1", "class2")                       │
│  ↳ Add one or more classes                                       │
│                                                                  │
│  element.classList.remove("class1", "class2")                    │
│  ↳ Remove one or more classes                                    │
│                                                                  │
│  element.classList.toggle("class")                               │
│  ↳ Add if missing, remove if present                             │
│                                                                  │
│  element.classList.toggle("class", condition)                    │
│  ↳ Force add (true) or remove (false)                            │
│                                                                  │
│  element.classList.contains("class")                             │
│  ↳ Check if class exists (returns boolean)                       │
│                                                                  │
│  element.classList.replace("old", "new")                         │
│  ↳ Replace one class with another                                │
│                                                                  │
│  element.className                                               │
│  ↳ Get/set entire class string                                   │
│                                                                  │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Basic Class Operations

const box = document.getElementById('box');

// Add classes
box.classList.add('active');
box.classList.add('highlight', 'animated', 'fade-in');

// Remove classes
box.classList.remove('hidden');
box.classList.remove('old-class', 'deprecated');

// Toggle class
box.classList.toggle('visible');

// Toggle with condition
const isLoggedIn = true;
box.classList.toggle('authenticated', isLoggedIn);

// Check for class
if (box.classList.contains('active')) {
  console.log('Box is active');
}

// Replace class
box.classList.replace('old-theme', 'new-theme');

className Property

const element = document.getElementById('myElement');

// Get all classes as string
console.log(element.className); // "class1 class2 class3"

// Set all classes (replaces existing)
element.className = 'new-class another-class';

// Append to existing (avoid - use classList.add instead)
element.className += ' additional-class';

Practical Examples

// Toggle dark mode
function toggleDarkMode() {
  document.body.classList.toggle('dark-mode');
}

// Tab switching
function activateTab(tabId) {
  // Remove active from all tabs
  document.querySelectorAll('.tab').forEach((tab) => {
    tab.classList.remove('active');
  });

  // Add active to clicked tab
  document.getElementById(tabId).classList.add('active');
}

// Conditional styling
function updateStatus(element, status) {
  element.classList.remove('success', 'error', 'pending');
  element.classList.add(status);
}

Inline Styles

style Property

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                    Inline Style Methods                          │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                                  │
│  element.style.property = value                                  │
│  ↳ Set individual CSS property                                   │
│                                                                  │
│  element.style.cssText = "..."                                   │
│  ↳ Set multiple styles as string                                 │
│                                                                  │
│  element.style.setProperty(name, value)                          │
│  ↳ Set property (supports CSS variables)                         │
│                                                                  │
│  element.style.removeProperty(name)                              │
│  ↳ Remove inline style                                           │
│                                                                  │
│  getComputedStyle(element)                                       │
│  ↳ Get final computed styles                                     │
│                                                                  │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Setting Inline Styles

const box = document.getElementById('box');

// Set individual properties (camelCase)
box.style.backgroundColor = 'blue';
box.style.fontSize = '16px';
box.style.marginTop = '20px';
box.style.borderRadius = '5px';

// CSS property names with hyphens → camelCase
// background-color → backgroundColor
// font-size → fontSize
// z-index → zIndex

// Set using setProperty (use CSS names)
box.style.setProperty('background-color', 'blue');
box.style.setProperty('--custom-color', 'red'); // CSS variables

Multiple Styles

const element = document.getElementById('myElement');

// Using cssText (replaces all inline styles)
element.style.cssText = `
    color: white;
    background-color: black;
    padding: 10px;
    border-radius: 5px;
`;

// Using Object.assign
Object.assign(element.style, {
  color: 'white',
  backgroundColor: 'black',
  padding: '10px',
  borderRadius: '5px',
});

// Using a style object helper
function applyStyles(element, styles) {
  Object.entries(styles).forEach(([prop, value]) => {
    element.style[prop] = value;
  });
}

applyStyles(element, {
  width: '200px',
  height: '100px',
  display: 'flex',
});

Getting Computed Styles

const element = document.getElementById('myElement');

// Get computed style (final rendered style)
const computedStyle = getComputedStyle(element);

console.log(computedStyle.width); // "200px"
console.log(computedStyle.backgroundColor); // "rgb(0, 0, 0)"
console.log(computedStyle.fontSize); // "16px"

// Get pseudo-element styles
const beforeStyle = getComputedStyle(element, '::before');
console.log(beforeStyle.content);

Removing Styles

const element = document.getElementById('myElement');

// Remove single property
element.style.backgroundColor = '';
// OR
element.style.removeProperty('background-color');

// Remove all inline styles
element.style.cssText = '';
// OR
element.removeAttribute('style');

Data Attributes

data-* Attributes

ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│                      Data Attributes                             │
ā”œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│                                                                  │
│  HTML:                                                           │
│  <div id="user"                                                  │
│       data-user-id="123"                                         │
│       data-user-name="John"                                      │
│       data-is-active="true">                                     │
│  </div>                                                          │
│                                                                  │
│  JavaScript Access:                                              │
│                                                                  │
│  element.dataset.userId      → "123"                             │
│  element.dataset.userName    → "John"                            │
│  element.dataset.isActive    → "true"                            │
│                                                                  │
│  Naming Convention:                                              │
│  data-user-id  →  dataset.userId   (kebab-case → camelCase)      │
│  data-user-name → dataset.userName                               │
│  data-is-active → dataset.isActive                               │
│                                                                  │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Reading Data Attributes

// HTML: <div id="product" data-product-id="456" data-price="29.99">

const product = document.getElementById('product');

// Using dataset (recommended)
console.log(product.dataset.productId); // "456"
console.log(product.dataset.price); // "29.99"

// Using getAttribute
console.log(product.getAttribute('data-product-id')); // "456"

// Get all data attributes
console.log(product.dataset);
// DOMStringMap { productId: "456", price: "29.99" }

Setting Data Attributes

const element = document.getElementById('item');

// Using dataset (recommended)
element.dataset.itemId = '789';
element.dataset.category = 'electronics';
element.dataset.inStock = 'true';

// Using setAttribute
element.setAttribute('data-item-id', '789');

// Dynamic data attribute
const key = 'color';
element.dataset[key] = 'blue';

Removing Data Attributes

const element = document.getElementById('item');

// Using delete
delete element.dataset.itemId;

// Using removeAttribute
element.removeAttribute('data-item-id');

Practical Use Cases

// Store component state
const modal = document.getElementById('modal');
modal.dataset.state = 'closed';

function toggleModal() {
  if (modal.dataset.state === 'closed') {
    modal.classList.add('open');
    modal.dataset.state = 'open';
  } else {
    modal.classList.remove('open');
    modal.dataset.state = 'closed';
  }
}

// Store configuration
const slider = document.getElementById('slider');
// <div id="slider" data-auto-play="true" data-delay="3000">

const autoPlay = slider.dataset.autoPlay === 'true';
const delay = parseInt(slider.dataset.delay, 10);

// Store relationships
// <button data-target="#modal1">Open Modal</button>

document.querySelectorAll('[data-target]').forEach((btn) => {
  btn.addEventListener('click', () => {
    const targetId = btn.dataset.target;
    document.querySelector(targetId).classList.toggle('visible');
  });
});

Comparison Tables

Content Properties Comparison

PropertyReturnsParses HTMLPerformanceHidden TextScript Content
innerHTMLHTML stringYesSlowerIncludesIncludes
textContentPlain textNoFasterIncludesIncludes
innerTextVisible textNoSlowest*ExcludesExcludes

*innerText triggers reflow to determine visibility

When to Use Each

Use CaseRecommended Property
Insert HTML contentinnerHTML (with sanitization)
Display user inputtextContent (XSS safe)
Get visible textinnerText
Clear elementinnerHTML = "" or textContent = ""
Copy text contenttextContent

Attribute Access Comparison

MethodUse CaseExample
Property accessStandard HTML attributeselement.id, element.href
getAttribute()Custom attributes, exact valueelement.getAttribute("data-id")
datasetdata-* attributeselement.dataset.id

Class Manipulation Comparison

MethodOld WayModern Way
Add classel.className += " new"el.classList.add("new")
Remove classComplex string manipulationel.classList.remove("old")
Toggle classCheck + add/removeel.classList.toggle("active")
Check classel.className.indexOf("...")el.classList.contains("...")

šŸ’” Key Takeaways

  1. •Content Modification: Use textContent for safety, innerHTML when you need HTML parsing
  2. •Attributes: Use dataset for data-* attributes, direct properties for standard attributes
  3. •Classes: Always use classList for class manipulation - it's cleaner and safer
  4. •Styles: Prefer CSS classes over inline styles; use getComputedStyle to read computed values
  5. •Security: Never use innerHTML with unsanitized user input

šŸ”— Next Steps

Continue to 10.3 Creating and Removing Elements to learn how to dynamically create, insert, and remove DOM elements.

.2 Modifying The DOM - JavaScript Tutorial | DeepML