javascript

examples

examples.js
/**
 * ============================================================
 * 10.2 Modifying the DOM - Examples
 * ============================================================
 *
 * This file demonstrates various ways to modify DOM elements
 * including content, attributes, classes, and styles.
 *
 * To run these examples:
 * 1. Create an HTML file with appropriate elements
 * 2. Link this script or paste into browser console
 */

// =============================================================
// EXAMPLE 1: innerHTML - Getting Content
// =============================================================
console.log('=== Example 1: innerHTML - Getting Content ===');

// HTML: <div id="container"><p>Hello <strong>World</strong></p></div>
const container = document.getElementById('container');

if (container) {
  // Get HTML content including tags
  console.log(container.innerHTML);
  // Output: "<p>Hello <strong>World</strong></p>"
}

// =============================================================
// EXAMPLE 2: innerHTML - Setting Content
// =============================================================
console.log('\n=== Example 2: innerHTML - Setting Content ===');

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

if (messageBox) {
  // Set HTML content - tags are parsed
  messageBox.innerHTML = '<h2>Welcome!</h2><p>Thanks for visiting.</p>';

  // Append to existing content
  messageBox.innerHTML += '<footer>© 2024</footer>';
}

// =============================================================
// EXAMPLE 3: innerHTML - Clear Content
// =============================================================
console.log('\n=== Example 3: innerHTML - Clear Content ===');

const clearableDiv = document.getElementById('clearable');

if (clearableDiv) {
  // Clear all content
  clearableDiv.innerHTML = '';
  console.log('Content cleared');
}

// =============================================================
// EXAMPLE 4: textContent - Getting Text
// =============================================================
console.log('\n=== Example 4: textContent - Getting Text ===');

// HTML: <p id="para">Hello <span>World</span>!</p>
const para = document.getElementById('para');

if (para) {
  // Gets all text, stripping HTML tags
  console.log(para.textContent);
  // Output: "Hello World!"
}

// =============================================================
// EXAMPLE 5: textContent - Setting Text Safely
// =============================================================
console.log('\n=== Example 5: textContent - Setting Text Safely ===');

const userDisplay = document.getElementById('userDisplay');
const userInput = "<script>alert('XSS')</script>"; // Malicious input

if (userDisplay) {
  // SAFE - HTML is escaped, displays as text
  userDisplay.textContent = userInput;
  // Shows: "<script>alert('XSS')</script>" as plain text

  console.log('User input safely displayed');
}

// =============================================================
// EXAMPLE 6: innerText vs textContent
// =============================================================
console.log('\n=== Example 6: innerText vs textContent ===');

// HTML: <div id="mixed">Visible<span style="display:none">Hidden</span></div>
const mixed = document.getElementById('mixed');

if (mixed) {
  console.log('textContent:', mixed.textContent);
  // Output: "VisibleHidden" (includes hidden text)

  console.log('innerText:', mixed.innerText);
  // Output: "Visible" (only visible text)
}

// =============================================================
// EXAMPLE 7: getAttribute and setAttribute
// =============================================================
console.log('\n=== Example 7: getAttribute and setAttribute ===');

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

if (link) {
  // Get attribute value
  const href = link.getAttribute('href');
  console.log('Current href:', href);

  // Set attribute value
  link.setAttribute('href', 'https://newsite.com');
  link.setAttribute('target', '_blank');
  link.setAttribute('rel', 'noopener noreferrer');

  console.log('Link attributes updated');
}

// =============================================================
// EXAMPLE 8: hasAttribute and removeAttribute
// =============================================================
console.log('\n=== Example 8: hasAttribute and removeAttribute ===');

const inputField = document.getElementById('email');

if (inputField) {
  // Check if attribute exists
  if (inputField.hasAttribute('disabled')) {
    console.log('Input is disabled, enabling...');
    inputField.removeAttribute('disabled');
  }

  // Add required attribute
  if (!inputField.hasAttribute('required')) {
    inputField.setAttribute('required', '');
  }
}

// =============================================================
// EXAMPLE 9: Property Access vs getAttribute
// =============================================================
console.log('\n=== Example 9: Property Access vs getAttribute ===');

// HTML: <a href="/page" id="navLink">Link</a>
const navLink = document.getElementById('navLink');

if (navLink) {
  // Property returns resolved URL
  console.log('Property href:', navLink.href);
  // Output: "https://example.com/page" (full URL)

  // getAttribute returns exact attribute value
  console.log('Attribute href:', navLink.getAttribute('href'));
  // Output: "/page" (relative path)
}

// =============================================================
// EXAMPLE 10: Iterating All Attributes
// =============================================================
console.log('\n=== Example 10: Iterating All Attributes ===');

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

if (element) {
  const attrs = element.attributes;
  console.log(`Element has ${attrs.length} attributes:`);

  for (const attr of attrs) {
    console.log(`  ${attr.name}: ${attr.value}`);
  }
}

// =============================================================
// EXAMPLE 11: classList.add() and classList.remove()
// =============================================================
console.log('\n=== Example 11: classList.add() and classList.remove() ===');

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

if (box) {
  // Add single class
  box.classList.add('active');

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

  console.log('Classes after add:', box.className);

  // Remove single class
  box.classList.remove('fade-in');

  // Remove multiple classes
  box.classList.remove('animated', 'highlighted');

  console.log('Classes after remove:', box.className);
}

// =============================================================
// EXAMPLE 12: classList.toggle()
// =============================================================
console.log('\n=== Example 12: classList.toggle() ===');

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

if (toggleBox) {
  // Toggle adds if missing, removes if present
  toggleBox.classList.toggle('visible');
  console.log('After toggle 1:', toggleBox.classList.contains('visible'));

  toggleBox.classList.toggle('visible');
  console.log('After toggle 2:', toggleBox.classList.contains('visible'));

  // Toggle with force parameter
  toggleBox.classList.toggle('active', true); // Always add
  toggleBox.classList.toggle('inactive', false); // Always remove
}

// =============================================================
// EXAMPLE 13: classList.contains() and classList.replace()
// =============================================================
console.log(
  '\n=== Example 13: classList.contains() and classList.replace() ==='
);

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

if (themeBox) {
  // Check if class exists
  if (themeBox.classList.contains('light-theme')) {
    console.log('Light theme is active');

    // Replace one class with another
    themeBox.classList.replace('light-theme', 'dark-theme');
    console.log('Switched to dark theme');
  }
}

// =============================================================
// EXAMPLE 14: className Property
// =============================================================
console.log('\n=== Example 14: className Property ===');

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

if (classBox) {
  // Get all classes as string
  console.log('Current classes:', classBox.className);

  // Set all classes (replaces existing)
  classBox.className = 'new-class another-class';
  console.log('After setting:', classBox.className);

  // Note: classList is preferred over className manipulation
}

// =============================================================
// EXAMPLE 15: Setting Inline Styles
// =============================================================
console.log('\n=== Example 15: Setting Inline Styles ===');

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

if (styledBox) {
  // Set individual properties (camelCase)
  styledBox.style.backgroundColor = '#3498db';
  styledBox.style.color = 'white';
  styledBox.style.padding = '20px';
  styledBox.style.borderRadius = '8px';
  styledBox.style.fontSize = '18px';
  styledBox.style.boxShadow = '0 2px 4px rgba(0,0,0,0.2)';

  console.log('Inline styles applied');
}

// =============================================================
// EXAMPLE 16: Using cssText
// =============================================================
console.log('\n=== Example 16: Using cssText ===');

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

if (cssTextBox) {
  // Set multiple styles at once
  cssTextBox.style.cssText = `
        width: 200px;
        height: 100px;
        background: linear-gradient(to right, #667eea, #764ba2);
        display: flex;
        align-items: center;
        justify-content: center;
        color: white;
        font-weight: bold;
    `;

  console.log('Multiple styles set via cssText');
}

// =============================================================
// EXAMPLE 17: Using Object.assign for Styles
// =============================================================
console.log('\n=== Example 17: Using Object.assign for Styles ===');

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

if (assignBox) {
  Object.assign(assignBox.style, {
    width: '150px',
    height: '150px',
    backgroundColor: '#2ecc71',
    border: '3px solid #27ae60',
    borderRadius: '50%',
    display: 'flex',
    alignItems: 'center',
    justifyContent: 'center',
  });

  console.log('Styles applied via Object.assign');
}

// =============================================================
// EXAMPLE 18: getComputedStyle
// =============================================================
console.log('\n=== Example 18: getComputedStyle ===');

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

if (computedBox) {
  // Get computed (final) styles
  const computed = getComputedStyle(computedBox);

  console.log('Computed width:', computed.width);
  console.log('Computed backgroundColor:', computed.backgroundColor);
  console.log('Computed fontSize:', computed.fontSize);
  console.log('Computed display:', computed.display);

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

// =============================================================
// EXAMPLE 19: Removing Inline Styles
// =============================================================
console.log('\n=== Example 19: Removing Inline Styles ===');

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

if (removeStyleBox) {
  // Remove single property by setting empty
  removeStyleBox.style.backgroundColor = '';

  // Remove using removeProperty
  removeStyleBox.style.removeProperty('padding');
  removeStyleBox.style.removeProperty('margin');

  // Remove all inline styles
  removeStyleBox.style.cssText = '';
  // OR: removeStyleBox.removeAttribute("style");

  console.log('Inline styles removed');
}

// =============================================================
// EXAMPLE 20: CSS Custom Properties (Variables)
// =============================================================
console.log('\n=== Example 20: CSS Custom Properties ===');

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

if (cssVarBox) {
  // Set CSS variable
  cssVarBox.style.setProperty('--primary-color', '#e74c3c');
  cssVarBox.style.setProperty('--spacing', '20px');
  cssVarBox.style.setProperty('--border-radius', '10px');

  // Read CSS variable
  const primaryColor =
    getComputedStyle(cssVarBox).getPropertyValue('--primary-color');
  console.log('Primary color:', primaryColor.trim());

  // Use the variable
  cssVarBox.style.backgroundColor = 'var(--primary-color)';
  cssVarBox.style.padding = 'var(--spacing)';
}

// =============================================================
// EXAMPLE 21: Data Attributes - Reading with dataset
// =============================================================
console.log('\n=== Example 21: Data Attributes - Reading ===');

// HTML: <div id="product" data-product-id="123" data-category="electronics" data-price="99.99">
const product = document.getElementById('product');

if (product) {
  // Access via dataset (camelCase)
  console.log('Product ID:', product.dataset.productId);
  console.log('Category:', product.dataset.category);
  console.log('Price:', product.dataset.price);

  // Get all data attributes
  console.log('All data:', product.dataset);
}

// =============================================================
// EXAMPLE 22: Data Attributes - Writing with dataset
// =============================================================
console.log('\n=== Example 22: Data Attributes - Writing ===');

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

if (item) {
  // Set data attributes
  item.dataset.itemId = '456';
  item.dataset.status = 'active';
  item.dataset.lastUpdated = new Date().toISOString();

  console.log('Data attributes set:');
  console.log('  data-item-id:', item.dataset.itemId);
  console.log('  data-status:', item.dataset.status);
}

// =============================================================
// EXAMPLE 23: Data Attributes - Deleting
// =============================================================
console.log('\n=== Example 23: Data Attributes - Deleting ===');

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

if (deletableItem) {
  // Add some data attributes first
  deletableItem.dataset.temp = 'temporary';
  deletableItem.dataset.toRemove = 'will be removed';

  console.log('Before delete:', Object.keys(deletableItem.dataset));

  // Delete using delete operator
  delete deletableItem.dataset.temp;

  // Delete using removeAttribute
  deletableItem.removeAttribute('data-to-remove');

  console.log('After delete:', Object.keys(deletableItem.dataset));
}

// =============================================================
// EXAMPLE 24: Practical - Toggle Dark Mode
// =============================================================
console.log('\n=== Example 24: Practical - Toggle Dark Mode ===');

function toggleDarkMode() {
  const body = document.body;

  body.classList.toggle('dark-mode');

  // Save preference
  const isDark = body.classList.contains('dark-mode');
  localStorage.setItem('darkMode', isDark);

  // Update button text
  const toggleBtn = document.getElementById('darkModeToggle');
  if (toggleBtn) {
    toggleBtn.textContent = isDark ? 'Light Mode' : 'Dark Mode';
  }

  return isDark;
}

// Initialize from saved preference
function initDarkMode() {
  const savedPref = localStorage.getItem('darkMode');
  if (savedPref === 'true') {
    document.body.classList.add('dark-mode');
  }
}

console.log('Dark mode toggle function created');

// =============================================================
// EXAMPLE 25: Practical - Tab Switching
// =============================================================
console.log('\n=== Example 25: Practical - Tab Switching ===');

function switchTab(tabId) {
  // Get all tabs and content panels
  const tabs = document.querySelectorAll('.tab');
  const panels = document.querySelectorAll('.tab-panel');

  // Remove active from all tabs
  tabs.forEach((tab) => {
    tab.classList.remove('active');
    tab.setAttribute('aria-selected', 'false');
  });

  // Hide all panels
  panels.forEach((panel) => {
    panel.classList.remove('active');
    panel.setAttribute('hidden', '');
  });

  // Activate selected tab
  const selectedTab = document.querySelector(`[data-tab="${tabId}"]`);
  const selectedPanel = document.getElementById(tabId);

  if (selectedTab && selectedPanel) {
    selectedTab.classList.add('active');
    selectedTab.setAttribute('aria-selected', 'true');

    selectedPanel.classList.add('active');
    selectedPanel.removeAttribute('hidden');
  }
}

console.log('Tab switching function created');

// =============================================================
// EXAMPLE 26: Practical - Form Validation Styling
// =============================================================
console.log('\n=== Example 26: Practical - Form Validation Styling ===');

function validateField(input) {
  const value = input.value.trim();
  const errorMessage = input.nextElementSibling; // Assumes error span follows input

  // Remove previous states
  input.classList.remove('valid', 'invalid');

  if (!value) {
    input.classList.add('invalid');
    if (errorMessage) {
      errorMessage.textContent = 'This field is required';
      errorMessage.style.display = 'block';
    }
    return false;
  }

  // Email validation
  if (input.type === 'email') {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    if (!emailRegex.test(value)) {
      input.classList.add('invalid');
      if (errorMessage) {
        errorMessage.textContent = 'Please enter a valid email';
        errorMessage.style.display = 'block';
      }
      return false;
    }
  }

  input.classList.add('valid');
  if (errorMessage) {
    errorMessage.style.display = 'none';
  }
  return true;
}

console.log('Form validation function created');

// =============================================================
// EXAMPLE 27: Practical - Progress Bar
// =============================================================
console.log('\n=== Example 27: Practical - Progress Bar ===');

function updateProgress(progressBar, percentage) {
  // Clamp percentage between 0 and 100
  percentage = Math.max(0, Math.min(100, percentage));

  // Update width
  progressBar.style.width = `${percentage}%`;

  // Update ARIA for accessibility
  progressBar.setAttribute('aria-valuenow', percentage);

  // Update data attribute
  progressBar.dataset.progress = percentage;

  // Update text if element exists
  const label = progressBar.querySelector('.progress-label');
  if (label) {
    label.textContent = `${percentage}%`;
  }

  // Change color based on progress
  progressBar.classList.remove('low', 'medium', 'high', 'complete');
  if (percentage < 25) {
    progressBar.classList.add('low');
  } else if (percentage < 50) {
    progressBar.classList.add('medium');
  } else if (percentage < 100) {
    progressBar.classList.add('high');
  } else {
    progressBar.classList.add('complete');
  }
}

console.log('Progress bar function created');

// =============================================================
// EXAMPLE 28: Practical - Tooltip System
// =============================================================
console.log('\n=== Example 28: Practical - Tooltip System ===');

function showTooltip(element) {
  const tooltipText = element.dataset.tooltip;
  if (!tooltipText) return;

  // Create tooltip element
  const tooltip = document.createElement('div');
  tooltip.className = 'tooltip';
  tooltip.textContent = tooltipText;
  tooltip.setAttribute('role', 'tooltip');

  // Position tooltip
  const rect = element.getBoundingClientRect();
  Object.assign(tooltip.style, {
    position: 'absolute',
    top: `${rect.bottom + window.scrollY + 8}px`,
    left: `${rect.left + window.scrollX + rect.width / 2}px`,
    transform: 'translateX(-50%)',
    backgroundColor: '#333',
    color: 'white',
    padding: '6px 12px',
    borderRadius: '4px',
    fontSize: '14px',
    zIndex: '1000',
  });

  // Add to DOM
  document.body.appendChild(tooltip);

  // Store reference for hiding
  element._tooltip = tooltip;
}

function hideTooltip(element) {
  if (element._tooltip) {
    element._tooltip.remove();
    delete element._tooltip;
  }
}

console.log('Tooltip system functions created');

// =============================================================
// EXAMPLE 29: Practical - Accordion
// =============================================================
console.log('\n=== Example 29: Practical - Accordion ===');

function toggleAccordionItem(header) {
  const item = header.parentElement;
  const content = item.querySelector('.accordion-content');
  const isOpen = item.classList.contains('open');

  // Toggle current item
  item.classList.toggle('open');

  // Update ARIA attributes
  header.setAttribute('aria-expanded', !isOpen);

  // Animate content
  if (!isOpen) {
    content.style.maxHeight = content.scrollHeight + 'px';
  } else {
    content.style.maxHeight = '0';
  }
}

// Close all other accordion items (optional - for exclusive mode)
function toggleAccordionExclusive(header) {
  const accordion = header.closest('.accordion');
  const allItems = accordion.querySelectorAll('.accordion-item');
  const currentItem = header.parentElement;

  allItems.forEach((item) => {
    if (item !== currentItem) {
      item.classList.remove('open');
      item
        .querySelector('.accordion-header')
        .setAttribute('aria-expanded', 'false');
      item.querySelector('.accordion-content').style.maxHeight = '0';
    }
  });

  toggleAccordionItem(header);
}

console.log('Accordion functions created');

// =============================================================
// EXAMPLE 30: Practical - Notification System
// =============================================================
console.log('\n=== Example 30: Practical - Notification System ===');

const NotificationManager = {
  container: null,

  init() {
    if (!this.container) {
      this.container = document.createElement('div');
      this.container.id = 'notification-container';
      Object.assign(this.container.style, {
        position: 'fixed',
        top: '20px',
        right: '20px',
        zIndex: '9999',
        display: 'flex',
        flexDirection: 'column',
        gap: '10px',
      });
      document.body.appendChild(this.container);
    }
  },

  show(message, type = 'info', duration = 3000) {
    this.init();

    const notification = document.createElement('div');
    notification.className = `notification notification-${type}`;
    notification.textContent = message;

    // Style based on type
    const colors = {
      info: '#3498db',
      success: '#2ecc71',
      warning: '#f39c12',
      error: '#e74c3c',
    };

    Object.assign(notification.style, {
      backgroundColor: colors[type] || colors.info,
      color: 'white',
      padding: '12px 24px',
      borderRadius: '4px',
      boxShadow: '0 2px 8px rgba(0,0,0,0.2)',
      transform: 'translateX(100%)',
      transition: 'transform 0.3s ease',
      cursor: 'pointer',
    });

    // Click to dismiss
    notification.addEventListener('click', () => this.dismiss(notification));

    // Add to container
    this.container.appendChild(notification);

    // Animate in
    requestAnimationFrame(() => {
      notification.style.transform = 'translateX(0)';
    });

    // Auto dismiss
    if (duration > 0) {
      notification.dataset.timeoutId = setTimeout(() => {
        this.dismiss(notification);
      }, duration);
    }

    return notification;
  },

  dismiss(notification) {
    // Clear timeout if exists
    if (notification.dataset.timeoutId) {
      clearTimeout(parseInt(notification.dataset.timeoutId));
    }

    // Animate out
    notification.style.transform = 'translateX(100%)';
    notification.style.opacity = '0';

    // Remove after animation
    setTimeout(() => {
      notification.remove();
    }, 300);
  },
};

console.log('Notification manager created');
console.log("Usage: NotificationManager.show('Hello!', 'success')");

// =============================================================
// Summary
// =============================================================
console.log('\n' + '='.repeat(60));
console.log('Examples Summary:');
console.log('='.repeat(60));
console.log('1-3: innerHTML - getting, setting, clearing content');
console.log('4-6: textContent and innerText differences');
console.log('7-10: Attribute manipulation methods');
console.log('11-14: classList manipulation');
console.log('15-20: Inline styles and computed styles');
console.log('21-23: Data attributes with dataset');
console.log('24-30: Practical applications');
console.log('='.repeat(60));
Examples - JavaScript Tutorial | DeepML