HTML & JS Topic

JavaScript DOM Manipulation

1. Selecting Elements

Basic Selectors

javascript

// Get element by ID (returns single element)
const header = document.getElementById('header');
const mainTitle = document.getElementById('main-title');

// Get elements by class name (returns HTMLCollection)
const buttons = document.getElementsByClassName('btn');
const menuItems = document.getElementsByClassName('menu-item');

// Get elements by tag name (returns HTMLCollection)
const paragraphs = document.getElementsByTagName('p');
const divs = document.getElementsByTagName('div');

Query Selectors (Modern & Powerful)

javascript

// Select first matching element
const firstButton = document.querySelector('.btn');
const mainNav = document.querySelector('#main-nav');
const firstParagraph = document.querySelector('p');

// Select all matching elements (returns NodeList)
const allButtons = document.querySelectorAll('.btn');
const allParagraphs = document.querySelectorAll('p');
const listItems = document.querySelectorAll('ul li');

// Complex CSS selectors
const activeLink = document.querySelector('nav a.active');
const firstChild = document.querySelector('ul > li:first-child');
const evenRows = document.querySelectorAll('tr:nth-child(even)');
const requiredInputs = document.querySelectorAll('input[required]');

Selecting Relative to Elements

javascript

const container = document.querySelector('.container');

// Children
const firstChild = container.firstElementChild;
const lastChild = container.lastElementChild;
const children = container.children; // HTMLCollection

// Parent
const parent = container.parentElement;
const parentNode = container.parentNode;

// Siblings
const nextSib = container.nextElementSibling;
const prevSib = container.previousElementSibling;

// Query within specific element
const innerButtons = container.querySelectorAll('.btn');
const firstInnerPara = container.querySelector('p');

Selecting Form Elements

javascript

// Form and form elements
const form = document.forms['registration'];
const formById = document.getElementById('registration-form');

// Form elements
const username = form.elements['username'];
const email = form.elements.email;
const password = form.querySelector('[type="password"]');

// Radio buttons and checkboxes
const genderRadios = document.querySelectorAll('input[name="gender"]');
const interestCheckboxes = document.querySelectorAll('input[name="interests"]');

2. Changing Content & Styles

Changing Text Content

javascript

// textContent (recommended for text only)
const title = document.querySelector('h1');
title.textContent = 'New Title Text'; // Sets plain text
console.log(title.textContent); // Gets text (including hidden elements)

// innerText (aware of styling)
title.innerText = 'Another Title'; // Respects CSS visibility
console.log(title.innerText); // Gets visible text only

// innerHTML (can include HTML)
const contentDiv = document.querySelector('.content');
contentDiv.innerHTML = '<strong>Bold text</strong> and normal text';

// Using insertAdjacentHTML (more flexible)
contentDiv.insertAdjacentHTML('beforeend', '<p>New paragraph</p>');
contentDiv.insertAdjacentHTML('afterbegin', '<h2>New heading</h2>');

// Methods:
// 'beforebegin' - Before the element
// 'afterbegin' - Inside, before first child
// 'beforeend' - Inside, after last child
// 'afterend' - After the element

Changing Attributes

javascript

const link = document.querySelector('a');
const image = document.querySelector('img');

// Get attribute
const href = link.getAttribute('href');
const src = image.getAttribute('src');

// Set attribute
link.setAttribute('href', 'https://newsite.com');
image.setAttribute('alt', 'New description');
link.setAttribute('target', '_blank');

// Remove attribute
link.removeAttribute('target');
image.removeAttribute('title');

// Toggle attribute (for boolean attributes)
const checkbox = document.querySelector('input[type="checkbox"]');
checkbox.toggleAttribute('checked'); // Toggles on/off
checkbox.toggleAttribute('disabled', true); // Force state

// Check if attribute exists
if (link.hasAttribute('target')) {
    console.log('Link opens in new tab');
}

// data-* attributes
const element = document.querySelector('[data-user-id]');
const userId = element.dataset.userId; // Get data-user-id
element.dataset.userRole = 'admin'; // Set data-user-role
element.dataset.loaded = 'true'; // Set data-loaded

Changing Styles

javascript

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

// Individual style properties
box.style.backgroundColor = 'blue';
box.style.color = 'white';
box.style.fontSize = '18px';
box.style.marginTop = '20px';
box.style.padding = '10px 20px';

// CSS custom properties (variables)
box.style.setProperty('--primary-color', '#007bff');
const primaryColor = box.style.getPropertyValue('--primary-color');

// Multiple styles at once
box.style.cssText = 'color: red; font-size: 20px; margin: 10px;';

// Reset/remove styles
box.style.color = ''; // Removes the style
box.style.removeProperty('font-size');

// Toggle classes (better for multiple styles)
box.classList.add('active', 'highlight');
box.classList.remove('inactive');
box.classList.toggle('visible'); // Toggles the class
box.classList.replace('old-class', 'new-class');

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

// Get computed style
const computedStyle = window.getComputedStyle(box);
const actualColor = computedStyle.color;
const actualMargin = computedStyle.marginTop;

Complete Styling Example

html

<div id="styled-box">Hello World</div>
<button onclick="styleBox()">Style Box</button>
<button onclick="toggleTheme()">Toggle Theme</button>

<script>
const box = document.getElementById('styled-box');

function styleBox() {
    // Direct styling
    box.style.cssText = `
        width: 200px;
        height: 100px;
        background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
        color: white;
        font-size: 24px;
        font-weight: bold;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 10px;
        box-shadow: 0 10px 20px rgba(0,0,0,0.2);
        transition: all 0.3s ease;
        cursor: pointer;
    `;
    
    // Add hover effect
    box.onmouseenter = () => {
        box.style.transform = 'translateY(-5px)';
        box.style.boxShadow = '0 15px 30px rgba(0,0,0,0.3)';
    };
    
    box.onmouseleave = () => {
        box.style.transform = 'translateY(0)';
        box.style.boxShadow = '0 10px 20px rgba(0,0,0,0.2)';
    };
}

function toggleTheme() {
    box.classList.toggle('dark-theme');
    
    if (box.classList.contains('dark-theme')) {
        box.style.backgroundColor = '#333';
        box.style.color = '#fff';
    } else {
        box.style.backgroundColor = '#f0f0f0';
        box.style.color = '#333';
    }
}
</script>

3. Creating & Removing Elements

Creating Elements

javascript

// Create new elements
const newDiv = document.createElement('div');
const newParagraph = document.createElement('p');
const newAnchor = document.createElement('a');
const newList = document.createElement('ul');

// Add content and attributes
newDiv.textContent = 'This is a new div';
newParagraph.innerHTML = 'This is <strong>bold</strong> text';
newAnchor.href = 'https://example.com';
newAnchor.textContent = 'Visit Example';
newAnchor.target = '_blank';

// Create element with attributes in one go
function createElement(tag, attributes = {}, content = '') {
    const element = document.createElement(tag);
    
    // Set attributes
    Object.entries(attributes).forEach(([key, value]) => {
        element.setAttribute(key, value);
    });
    
    // Set content
    if (content) {
        element.textContent = content;
    }
    
    return element;
}

// Usage
const newButton = createElement('button', {
    class: 'btn btn-primary',
    type: 'button',
    'data-action': 'submit'
}, 'Click Me');

Appending Elements

javascript

const container = document.querySelector('.container');

// Append at the end
container.appendChild(newDiv);

// Insert before specific element
const firstChild = container.firstElementChild;
container.insertBefore(newParagraph, firstChild);

// Insert at specific position
const thirdChild = container.children[2];
container.insertBefore(newDiv, thirdChild);

// Using insertAdjacentElement
const referenceElement = document.querySelector('.reference');
referenceElement.insertAdjacentElement('afterend', newDiv);

// Append multiple elements
const fragment = document.createDocumentFragment();
fragment.appendChild(createElement('p', {}, 'First paragraph'));
fragment.appendChild(createElement('p', {}, 'Second paragraph'));
fragment.appendChild(createElement('p', {}, 'Third paragraph'));
container.appendChild(fragment); // Single DOM operation!

// Prepend (add at beginning)
container.prepend(newDiv);

// Insert at specific index
function insertAt(parent, element, index) {
    const children = parent.children;
    if (index >= children.length) {
        parent.appendChild(element);
    } else {
        parent.insertBefore(element, children[index]);
    }
}

Removing Elements

javascript

const elementToRemove = document.querySelector('.remove-me');

// Remove from parent
elementToRemove.parentNode.removeChild(elementToRemove);

// Modern way (ES5+)
elementToRemove.remove();

// Remove all children
const list = document.querySelector('ul');

// Method 1: While loop (fast)
while (list.firstChild) {
    list.removeChild(list.firstChild);
}

// Method 2: innerHTML (fastest but be careful)
list.innerHTML = '';

// Method 3: textContent (for text-only removal)
list.textContent = '';

// Method 4: Remove specific children
const items = list.querySelectorAll('li');
items.forEach(item => item.remove());

// Remove self
function removeSelf() {
    this.remove(); // 'this' refers to the element
}

// Remove after delay
setTimeout(() => {
    const tempMessage = document.querySelector('.temp-message');
    if (tempMessage) {
        tempMessage.remove();
    }
}, 3000);

Replacing Elements

javascript

const oldElement = document.querySelector('.old');
const newElement = document.createElement('div');
newElement.textContent = 'I am the replacement!';
newElement.className = 'new';

// Replace element
oldElement.parentNode.replaceChild(newElement, oldElement);

// Modern way
oldElement.replaceWith(newElement);

// Replace with multiple elements
oldElement.replaceWith(
    createElement('h2', {}, 'New Heading'),
    createElement('p', {}, 'New paragraph content'),
    createElement('button', {class: 'btn'}, 'Click me')
);

// Replace content (keeping the element)
oldElement.innerHTML = '<span>Completely new content</span>';

4. Practical Examples

Example 1: Dynamic List Manager

html

<div class="list-manager">
    <h2>Task List</h2>
    <input type="text" id="task-input" placeholder="Enter a new task">
    <button onclick="addTask()">Add Task</button>
    
    <ul id="task-list"></ul>
    
    <div class="stats">
        <p>Total tasks: <span id="task-count">0</span></p>
        <p>Completed: <span id="completed-count">0</span></p>
    </div>
</div>

<script>
const taskInput = document.getElementById('task-input');
const taskList = document.getElementById('task-list');
let taskCount = 0;
let completedCount = 0;

function addTask() {
    const taskText = taskInput.value.trim();
    if (!taskText) return;
    
    // Create list item
    const li = document.createElement('li');
    li.className = 'task-item';
    
    // Create task text span
    const textSpan = document.createElement('span');
    textSpan.textContent = taskText;
    textSpan.className = 'task-text';
    
    // Create complete button
    const completeBtn = document.createElement('button');
    completeBtn.textContent = '✓';
    completeBtn.className = 'complete-btn';
    completeBtn.onclick = function() {
        li.classList.toggle('completed');
        textSpan.style.textDecoration = li.classList.contains('completed') 
            ? 'line-through' : 'none';
        updateStats();
    };
    
    // Create delete button
    const deleteBtn = document.createElement('button');
    deleteBtn.textContent = '×';
    deleteBtn.className = 'delete-btn';
    deleteBtn.onclick = function() {
        li.remove();
        updateStats();
    };
    
    // Assemble the item
    li.appendChild(completeBtn);
    li.appendChild(textSpan);
    li.appendChild(deleteBtn);
    
    // Add to list
    taskList.appendChild(li);
    
    // Clear input and update stats
    taskInput.value = '';
    updateStats();
    
    // Focus back on input
    taskInput.focus();
}

function updateStats() {
    const items = document.querySelectorAll('.task-item');
    const completed = document.querySelectorAll('.task-item.completed');
    
    taskCount = items.length;
    completedCount = completed.length;
    
    document.getElementById('task-count').textContent = taskCount;
    document.getElementById('completed-count').textContent = completedCount;
}

// Add task on Enter key
taskInput.addEventListener('keypress', (e) => {
    if (e.key === 'Enter') addTask();
});
</script>

<style>
.list-manager {
    max-width: 400px;
    margin: 20px auto;
    padding: 20px;
    border: 1px solid #ddd;
    border-radius: 8px;
}
#task-input {
    width: 70%;
    padding: 8px;
    margin-right: 10px;
}
button {
    padding: 8px 16px;
    background: #007bff;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
#task-list {
    list-style: none;
    padding: 0;
    margin: 20px 0;
}
.task-item {
    display: flex;
    align-items: center;
    padding: 10px;
    margin: 5px 0;
    background: #f8f9fa;
    border-radius: 4px;
}
.task-text {
    flex: 1;
    margin: 0 10px;
}
.complete-btn, .delete-btn {
    padding: 5px 10px;
    margin: 0 2px;
    border: none;
    border-radius: 3px;
    cursor: pointer;
}
.complete-btn {
    background: #28a745;
    color: white;
}
.delete-btn {
    background: #dc3545;
    color: white;
}
.completed .task-text {
    text-decoration: line-through;
    color: #6c757d;
}
.stats {
    display: flex;
    justify-content: space-between;
    margin-top: 20px;
    padding-top: 10px;
    border-top: 1px solid #ddd;
}
</style>

Example 2: Dynamic Form Builder

html

<div class="form-builder">
    <h2>Dynamic Form Builder</h2>
    
    <div class="controls">
        <button onclick="addTextInput()">Add Text Input</button>
        <button onclick="addEmailInput()">Add Email Input</button>
        <button onclick="addSelect()">Add Dropdown</button>
        <button onclick="addCheckbox()">Add Checkbox</button>
        <button onclick="clearForm()">Clear Form</button>
    </div>
    
    <form id="dynamic-form">
        <!-- Form elements will be added here -->
    </form>
    
    <button onclick="submitForm()" style="margin-top: 20px;">Submit Form</button>
    
    <div id="form-preview"></div>
</div>

<script>
const form = document.getElementById('dynamic-form');
const formPreview = document.getElementById('form-preview');
let fieldCount = 0;

function addTextInput() {
    fieldCount++;
    const fieldId = `field-${fieldCount}`;
    
    const fieldGroup = document.createElement('div');
    fieldGroup.className = 'form-group';
    
    const label = document.createElement('label');
    label.htmlFor = fieldId;
    label.textContent = `Text Field ${fieldCount}`;
    
    const input = document.createElement('input');
    input.type = 'text';
    input.id = fieldId;
    input.name = fieldId;
    input.placeholder = 'Enter text...';
    input.required = true;
    
    const removeBtn = document.createElement('button');
    removeBtn.type = 'button';
    removeBtn.textContent = 'Remove';
    removeBtn.className = 'remove-btn';
    removeBtn.onclick = () => fieldGroup.remove();
    
    fieldGroup.appendChild(label);
    fieldGroup.appendChild(input);
    fieldGroup.appendChild(removeBtn);
    
    form.appendChild(fieldGroup);
}

function addEmailInput() {
    fieldCount++;
    const fieldId = `email-${fieldCount}`;
    
    const fieldGroup = document.createElement('div');
    fieldGroup.className = 'form-group';
    
    const label = document.createElement('label');
    label.htmlFor = fieldId;
    label.textContent = `Email ${fieldCount}`;
    
    const input = document.createElement('input');
    input.type = 'email';
    input.id = fieldId;
    input.name = fieldId;
    input.placeholder = 'user@example.com';
    input.required = true;
    
    const removeBtn = document.createElement('button');
    removeBtn.type = 'button';
    removeBtn.textContent = 'Remove';
    removeBtn.className = 'remove-btn';
    removeBtn.onclick = () => fieldGroup.remove();
    
    fieldGroup.appendChild(label);
    fieldGroup.appendChild(input);
    fieldGroup.appendChild(removeBtn);
    
    form.appendChild(fieldGroup);
}

function addSelect() {
    fieldCount++;
    const fieldId = `select-${fieldCount}`;
    
    const fieldGroup = document.createElement('div');
    fieldGroup.className = 'form-group';
    
    const label = document.createElement('label');
    label.htmlFor = fieldId;
    label.textContent = `Dropdown ${fieldCount}`;
    
    const select = document.createElement('select');
    select.id = fieldId;
    select.name = fieldId;
    
    const options = ['Option 1', 'Option 2', 'Option 3'];
    options.forEach((optionText, index) => {
        const option = document.createElement('option');
        option.value = `opt-${index + 1}`;
        option.textContent = optionText;
        select.appendChild(option);
    });
    
    const removeBtn = document.createElement('button');
    removeBtn.type = 'button';
    removeBtn.textContent = 'Remove';
    removeBtn.className = 'remove-btn';
    removeBtn.onclick = () => fieldGroup.remove();
    
    fieldGroup.appendChild(label);
    fieldGroup.appendChild(select);
    fieldGroup.appendChild(removeBtn);
    
    form.appendChild(fieldGroup);
}

function addCheckbox() {
    fieldCount++;
    const fieldId = `checkbox-${fieldCount}`;
    
    const fieldGroup = document.createElement('div');
    fieldGroup.className = 'form-group checkbox-group';
    
    const label = document.createElement('label');
    const input = document.createElement('input');
    input.type = 'checkbox';
    input.id = fieldId;
    input.name = fieldId;
    input.value = 'checked';
    
    const span = document.createElement('span');
    span.textContent = `Checkbox ${fieldCount}`;
    
    label.appendChild(input);
    label.appendChild(span);
    
    const removeBtn = document.createElement('button');
    removeBtn.type = 'button';
    removeBtn.textContent = 'Remove';
    removeBtn.className = 'remove-btn';
    removeBtn.onclick = () => fieldGroup.remove();
    
    fieldGroup.appendChild(label);
    fieldGroup.appendChild(removeBtn);
    
    form.appendChild(fieldGroup);
}

function clearForm() {
    form.innerHTML = '';
    fieldCount = 0;
    formPreview.innerHTML = '';
}

function submitForm() {
    const formData = new FormData(form);
    const data = {};
    
    for (let [key, value] of formData.entries()) {
        data[key] = value;
    }
    
    // Display form data
    formPreview.innerHTML = '<h3>Form Data:</h3>';
    
    if (Object.keys(data).length === 0) {
        formPreview.innerHTML += '<p>No form data to display</p>';
        return;
    }
    
    const pre = document.createElement('pre');
    pre.textContent = JSON.stringify(data, null, 2);
    formPreview.appendChild(pre);
    
    // In real application, you would send data to server
    console.log('Form data:', data);
}
</script>

<style>
.form-builder {
    max-width: 600px;
    margin: 20px auto;
    padding: 20px;
    border: 1px solid #ddd;
    border-radius: 8px;
}
.controls {
    margin-bottom: 20px;
}
.controls button {
    margin: 0 5px 5px 0;
    padding: 8px 16px;
    background: #6c757d;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
.controls button:hover {
    background: #5a6268;
}
.form-group {
    margin-bottom: 15px;
    padding: 10px;
    background: #f8f9fa;
    border-radius: 4px;
}
.form-group label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}
.form-group input[type="text"],
.form-group input[type="email"],
.form-group select {
    width: 100%;
    padding: 8px;
    border: 1px solid #ced4da;
    border-radius: 4px;
    box-sizing: border-box;
}
.checkbox-group label {
    display: flex;
    align-items: center;
    font-weight: normal;
    cursor: pointer;
}
.checkbox-group input[type="checkbox"] {
    margin-right: 8px;
}
.remove-btn {
    margin-top: 5px;
    padding: 4px 8px;
    background: #dc3545;
    color: white;
    border: none;
    border-radius: 3px;
    cursor: pointer;
}
#form-preview {
    margin-top: 20px;
    padding: 15px;
    background: #e9ecef;
    border-radius: 4px;
}
pre {
    background: white;
    padding: 10px;
    border-radius: 4px;
    overflow: auto;
}
</style>

Example 3: Live Style Editor

html

<div class="style-editor">
    <h2>Live Style Editor</h2>
    
    <div class="editor-container">
        <div class="target-box" id="target-box">
            Edit my styles!
        </div>
        
        <div class="controls">
            <div class="control-group">
                <label>Background Color:</label>
                <input type="color" id="bg-color" value="#3498db">
                <input type="text" id="bg-color-text" value="#3498db" placeholder="#hex or color name">
            </div>
            
            <div class="control-group">
                <label>Text Color:</label>
                <input type="color" id="text-color" value="#ffffff">
                <input type="text" id="text-color-text" value="#ffffff">
            </div>
            
            <div class="control-group">
                <label>Font Size: <span id="font-size-value">16px</span></label>
                <input type="range" id="font-size" min="8" max="72" value="16">
            </div>
            
            <div class="control-group">
                <label>Border Radius: <span id="border-radius-value">8px</span></label>
                <input type="range" id="border-radius" min="0" max="50" value="8">
            </div>
            
            <div class="control-group">
                <label>Width: <span id="width-value">300px</span></label>
                <input type="range" id="width" min="100" max="500" value="300">
            </div>
            
            <div class="control-group">
                <label>Height: <span id="height-value">200px</span></label>
                <input type="range" id="height" min="50" max="400" value="200">
            </div>
            
            <div class="checkbox-group">
                <label>
                    <input type="checkbox" id="bold-text"> Bold Text
                </label>
                <label>
                    <input type="checkbox" id="italic-text"> Italic Text
                </label>
                <label>
                    <input type="checkbox" id="shadow"> Add Shadow
                </label>
            </div>
            
            <button onclick="resetStyles()">Reset Styles</button>
            <button onclick="copyStyles()">Copy CSS</button>
        </div>
    </div>
    
    <div class="css-output">
        <h3>Generated CSS:</h3>
        <pre id="css-code">#target-box {}</pre>
    </div>
</div>

<script>
const targetBox = document.getElementById('target-box');
const cssCode = document.getElementById('css-code');

// Color inputs
const bgColor = document.getElementById('bg-color');
const bgColorText = document.getElementById('bg-color-text');
const textColor = document.getElementById('text-color');
const textColorText = document.getElementById('text-color-text');

// Range inputs
const fontSize = document.getElementById('font-size');
const borderRadius = document.getElementById('border-radius');
const width = document.getElementById('width');
const height = document.getElementById('height');

// Checkboxes
const boldText = document.getElementById('bold-text');
const italicText = document.getElementById('italic-text');
const shadow = document.getElementById('shadow');

// Value displays
const fontSizeValue = document.getElementById('font-size-value');
const borderRadiusValue = document.getElementById('border-radius-value');
const widthValue = document.getElementById('width-value');
const heightValue = document.getElementById('height-value');

// Initialize
updateStyles();
updateCSSOutput();

// Event listeners for color inputs
bgColor.addEventListener('input', () => {
    bgColorText.value = bgColor.value;
    updateStyles();
});

bgColorText.addEventListener('input', () => {
    bgColor.value = bgColorText.value;
    updateStyles();
});

textColor.addEventListener('input', () => {
    textColorText.value = textColor.value;
    updateStyles();
});

textColorText.addEventListener('input', () => {
    textColor.value = textColorText.value;
    updateStyles();
});

// Event listeners for range inputs
fontSize.addEventListener('input', () => {
    fontSizeValue.textContent = `${fontSize.value}px`;
    updateStyles();
});

borderRadius.addEventListener('input', () => {
    borderRadiusValue.textContent = `${borderRadius.value}px`;
    updateStyles();
});

width.addEventListener('input', () => {
    widthValue.textContent = `${width.value}px`;
    updateStyles();
});

height.addEventListener('input', () => {
    heightValue.textContent = `${height.value}px`;
    updateStyles();
});

// Event listeners for checkboxes
boldText.addEventListener('change', updateStyles);
italicText.addEventListener('change', updateStyles);
shadow.addEventListener('change', updateStyles);

function updateStyles() {
    // Apply styles to target box
    targetBox.style.backgroundColor = bgColor.value;
    targetBox.style.color = textColor.value;
    targetBox.style.fontSize = `${fontSize.value}px`;
    targetBox.style.borderRadius = `${borderRadius.value}px`;
    targetBox.style.width = `${width.value}px`;
    targetBox.style.height = `${height.value}px`;
    
    // Font weight and style
    targetBox.style.fontWeight = boldText.checked ? 'bold' : 'normal';
    targetBox.style.fontStyle = italicText.checked ? 'italic' : 'normal';
    
    // Box shadow
    if (shadow.checked) {
        targetBox.style.boxShadow = '0 10px 20px rgba(0,0,0,0.2)';
    } else {
        targetBox.style.boxShadow = 'none';
    }
    
    // Update CSS output
    updateCSSOutput();
}

function updateCSSOutput() {
    const styles = `
#target-box {
    background-color: ${bgColor.value};
    color: ${textColor.value};
    font-size: ${fontSize.value}px;
    border-radius: ${borderRadius.value}px;
    width: ${width.value}px;
    height: ${height.value}px;
    font-weight: ${boldText.checked ? 'bold' : 'normal'};
    font-style: ${italicText.checked ? 'italic' : 'normal'};
    box-shadow: ${shadow.checked ? '0 10px 20px rgba(0,0,0,0.2)' : 'none'};
    display: flex;
    align-items: center;
    justify-content: center;
    transition: all 0.3s ease;
}`;
    
    cssCode.textContent = styles;
}

function resetStyles() {
    // Reset inputs
    bgColor.value = '#3498db';
    bgColorText.value = '#3498db';
    textColor.value = '#ffffff';
    textColorText.value = '#ffffff';
    fontSize.value = 16;
    borderRadius.value = 8;
    width.value = 300;
    height.value = 200;
    boldText.checked = false;
    italicText.checked = false;
    shadow.checked = false;
    
    // Update displays
    fontSizeValue.textContent = '16px';
    borderRadiusValue.textContent = '8px';
    widthValue.textContent = '300px';
    heightValue.textContent = '200px';
    
    // Apply styles
    updateStyles();
}

function copyStyles() {
    const cssText = cssCode.textContent;
    navigator.clipboard.writeText(cssText).then(() => {
        alert('CSS copied to clipboard!');
    }).catch(err => {
        console.error('Failed to copy: ', err);
        // Fallback
        const textArea = document.createElement('textarea');
        textArea.value = cssText;
        document.body.appendChild(textArea);
        textArea.select();
        document.execCommand('copy');
        document.body.removeChild(textArea);
        alert('CSS copied to clipboard!');
    });
}
</script>

<style>
.style-editor {
    max-width: 800px;
    margin: 20px auto;
    padding: 20px;
    border: 1px solid #ddd;
    border-radius: 8px;
}
.editor-container {
    display: flex;
    gap: 30px;
    margin: 20px 0;
}
.target-box {
    display: flex;
    align-items: center;
    justify-content: center;
    border: 2px solid #ddd;
    font-family: Arial, sans-serif;
    transition: all 0.3s ease;
}
.controls {
    flex: 1;
}
.control-group {
    margin-bottom: 15px;
}
.control-group label {
    display: block;
    margin-bottom: 5px;
    font-weight: bold;
}
.control-group input[type="color"] {
    width: 50px;
    height: 30px;
    vertical-align: middle;
    margin-right: 10px;
}
.control-group input[type="text"] {
    width: 120px;
    padding: 5px;
    border: 1px solid #ced4da;
    border-radius: 4px;
}
.control-group input[type="range"] {
    width: 100%;
}
.checkbox-group {
    margin: 20px 0;
}
.checkbox-group label {
    display: block;
    margin: 5px 0;
    cursor: pointer;
}
.checkbox-group input[type="checkbox"] {
    margin-right: 8px;
}
.css-output {
    margin-top: 30px;
    padding: 15px;
    background: #2c3e50;
    border-radius: 4px;
}
.css-output h3 {
    color: white;
    margin-top: 0;
}
#css-code {
    background: #34495e;
    color: #ecf0f1;
    padding: 15px;
    border-radius: 4px;
    overflow: auto;
    font-family: 'Courier New', monospace;
    font-size: 14px;
}
button {
    padding: 8px 16px;
    margin-right: 10px;
    background: #007bff;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
}
button:hover {
    background: #0056b3;
}
</style>

Key Points to Remember

  1. Use querySelector/querySelectorAll for modern element selection

  2. Prefer textContent over innerHTML for security when dealing with text

  3. Use classList methods for CSS class manipulation

  4. Batch DOM operations using DocumentFragment for better performance

  5. Cache DOM selections if you use them multiple times

  6. Separate concerns - Keep JavaScript, CSS, and HTML separate when possible

  7. Always validate user input when creating dynamic content

  8. Consider accessibility when manipulating the DOM

  9. Use event delegation for dynamically created elements

  10. Clean up event listeners when removing elements

DOM manipulation is at the core of interactive web development. Mastering these techniques allows you to create dynamic, responsive, and engaging web applications.

Comments (0)

No comments yet. Be the first to comment!

LecturreAI Assistant

Hello! I'm LecturreAI

What would you like to learn today?