Skip to main content
โšก Calmops

Modifying DOM: Creating, Updating, Deleting Elements

Modifying DOM: Creating, Updating, Deleting Elements

Dynamic DOM manipulation is essential for creating interactive web applications. Learn how to create, update, and delete elements.

Creating Elements

createElement()

// Create a new element
const div = document.createElement("div");
const p = document.createElement("p");
const button = document.createElement("button");

// Set properties
div.className = "container";
p.textContent = "Hello World";
button.textContent = "Click me";

createTextNode()

const text = document.createTextNode("Some text");
const p = document.createElement("p");
p.appendChild(text);

innerHTML

const container = document.getElementById("container");

// Set HTML content
container.innerHTML = "<h1>Title</h1><p>Paragraph</p>";

// Append HTML
container.innerHTML += "<button>New Button</button>";

insertAdjacentHTML()

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

// Insert before element
element.insertAdjacentHTML("beforebegin", "<p>Before</p>");

// Insert inside, before children
element.insertAdjacentHTML("afterbegin", "<p>Start</p>");

// Insert inside, after children
element.insertAdjacentHTML("beforeend", "<p>End</p>");

// Insert after element
element.insertAdjacentHTML("afterend", "<p>After</p>");

Adding Elements to DOM

appendChild()

const parent = document.getElementById("parent");
const newElement = document.createElement("div");
newElement.textContent = "New element";

// Add as last child
parent.appendChild(newElement);

insertBefore()

const parent = document.getElementById("parent");
const newElement = document.createElement("div");
const referenceElement = parent.firstChild;

// Insert before reference element
parent.insertBefore(newElement, referenceElement);

append() and prepend()

const parent = document.getElementById("parent");

// Append multiple elements
parent.append(
    document.createElement("div"),
    document.createElement("p"),
    "Text node"
);

// Prepend elements
parent.prepend(document.createElement("h1"));

Updating Elements

textContent

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

// Get text
console.log(element.textContent);

// Set text
element.textContent = "New text";

innerHTML

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

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

// Set HTML
element.innerHTML = "<strong>Bold text</strong>";

Attributes

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

// Set attribute
element.setAttribute("data-id", "123");
element.setAttribute("class", "active");

// Get attribute
console.log(element.getAttribute("data-id"));

// Remove attribute
element.removeAttribute("disabled");

// Check attribute
if (element.hasAttribute("data-id")) {
    console.log("Has data-id");
}

Properties

const input = document.getElementById("myInput");

// Set value
input.value = "New value";

// Set disabled
input.disabled = true;

// Set checked
const checkbox = document.getElementById("myCheckbox");
checkbox.checked = true;

Classes

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

// Add class
element.classList.add("active");

// Remove class
element.classList.remove("active");

// Toggle class
element.classList.toggle("active");

// Check class
if (element.classList.contains("active")) {
    console.log("Has active class");
}

// Replace class
element.classList.replace("old-class", "new-class");

Styles

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

// Set inline styles
element.style.color = "red";
element.style.backgroundColor = "blue";
element.style.fontSize = "20px";
element.style.padding = "10px";

// Get computed styles
const styles = window.getComputedStyle(element);
console.log(styles.color);
console.log(styles.backgroundColor);

Removing Elements

remove()

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

// Remove element from DOM
element.remove();

removeChild()

const parent = document.getElementById("parent");
const child = document.getElementById("child");

// Remove child from parent
parent.removeChild(child);

innerHTML = ""

const container = document.getElementById("container");

// Clear all children
container.innerHTML = "";

Cloning Elements

cloneNode()

const original = document.getElementById("original");

// Shallow clone (no children)
const shallowClone = original.cloneNode(false);

// Deep clone (with children)
const deepClone = original.cloneNode(true);

document.body.appendChild(deepClone);

Practical Examples

Dynamic List Creation

function createList(items) {
    const ul = document.createElement("ul");
    
    items.forEach(item => {
        const li = document.createElement("li");
        li.textContent = item;
        ul.appendChild(li);
    });
    
    return ul;
}

const list = createList(["Apple", "Banana", "Orange"]);
document.body.appendChild(list);

Dynamic Table Creation

function createTable(data) {
    const table = document.createElement("table");
    
    // Create header
    const thead = document.createElement("thead");
    const headerRow = document.createElement("tr");
    
    Object.keys(data[0]).forEach(key => {
        const th = document.createElement("th");
        th.textContent = key;
        headerRow.appendChild(th);
    });
    
    thead.appendChild(headerRow);
    table.appendChild(thead);
    
    // Create body
    const tbody = document.createElement("tbody");
    
    data.forEach(row => {
        const tr = document.createElement("tr");
        
        Object.values(row).forEach(value => {
            const td = document.createElement("td");
            td.textContent = value;
            tr.appendChild(td);
        });
        
        tbody.appendChild(tr);
    });
    
    table.appendChild(tbody);
    return table;
}

const data = [
    { name: "Alice", age: 30, city: "New York" },
    { name: "Bob", age: 25, city: "Boston" }
];

document.body.appendChild(createTable(data));

Todo List Application

class TodoList {
    constructor(containerId) {
        this.container = document.getElementById(containerId);
        this.todos = [];
        this.setupUI();
    }
    
    setupUI() {
        const input = document.createElement("input");
        input.type = "text";
        input.placeholder = "Add a todo";
        
        const button = document.createElement("button");
        button.textContent = "Add";
        button.addEventListener("click", () => this.addTodo(input.value));
        
        this.list = document.createElement("ul");
        
        this.container.appendChild(input);
        this.container.appendChild(button);
        this.container.appendChild(this.list);
    }
    
    addTodo(text) {
        if (!text) return;
        
        const todo = { id: Date.now(), text, completed: false };
        this.todos.push(todo);
        
        this.renderTodos();
    }
    
    removeTodo(id) {
        this.todos = this.todos.filter(t => t.id !== id);
        this.renderTodos();
    }
    
    toggleTodo(id) {
        const todo = this.todos.find(t => t.id === id);
        if (todo) {
            todo.completed = !todo.completed;
            this.renderTodos();
        }
    }
    
    renderTodos() {
        this.list.innerHTML = "";
        
        this.todos.forEach(todo => {
            const li = document.createElement("li");
            
            const checkbox = document.createElement("input");
            checkbox.type = "checkbox";
            checkbox.checked = todo.completed;
            checkbox.addEventListener("change", () => this.toggleTodo(todo.id));
            
            const span = document.createElement("span");
            span.textContent = todo.text;
            if (todo.completed) {
                span.style.textDecoration = "line-through";
            }
            
            const deleteBtn = document.createElement("button");
            deleteBtn.textContent = "Delete";
            deleteBtn.addEventListener("click", () => this.removeTodo(todo.id));
            
            li.appendChild(checkbox);
            li.appendChild(span);
            li.appendChild(deleteBtn);
            this.list.appendChild(li);
        });
    }
}

// Usage
const todoList = new TodoList("todoContainer");

Dynamic Form Builder

class FormBuilder {
    constructor(containerId) {
        this.container = document.getElementById(containerId);
        this.form = document.createElement("form");
        this.fields = [];
    }
    
    addField(type, name, label) {
        const fieldGroup = document.createElement("div");
        fieldGroup.className = "field-group";
        
        const labelElement = document.createElement("label");
        labelElement.textContent = label;
        labelElement.htmlFor = name;
        
        const input = document.createElement("input");
        input.type = type;
        input.name = name;
        input.id = name;
        
        fieldGroup.appendChild(labelElement);
        fieldGroup.appendChild(input);
        this.form.appendChild(fieldGroup);
        
        this.fields.push({ name, input });
        return this;
    }
    
    addSubmitButton(text = "Submit") {
        const button = document.createElement("button");
        button.type = "submit";
        button.textContent = text;
        this.form.appendChild(button);
        return this;
    }
    
    render() {
        this.container.appendChild(this.form);
    }
    
    getValues() {
        const values = {};
        this.fields.forEach(field => {
            values[field.name] = field.input.value;
        });
        return values;
    }
}

// Usage
const builder = new FormBuilder("formContainer");
builder
    .addField("text", "name", "Name:")
    .addField("email", "email", "Email:")
    .addField("password", "password", "Password:")
    .addSubmitButton("Register")
    .render();

builder.form.addEventListener("submit", (e) => {
    e.preventDefault();
    console.log(builder.getValues());
});

Batch DOM Updates

// Bad - causes multiple reflows
const container = document.getElementById("container");
for (let i = 0; i < 1000; i++) {
    const div = document.createElement("div");
    div.textContent = `Item ${i}`;
    container.appendChild(div); // Reflow each time
}

// Good - batch updates
const container = document.getElementById("container");
const fragment = document.createDocumentFragment();

for (let i = 0; i < 1000; i++) {
    const div = document.createElement("div");
    div.textContent = `Item ${i}`;
    fragment.appendChild(div);
}

container.appendChild(fragment); // Single reflow

Performance Tips

Use DocumentFragment

const fragment = document.createDocumentFragment();

for (let i = 0; i < 100; i++) {
    const li = document.createElement("li");
    li.textContent = `Item ${i}`;
    fragment.appendChild(li);
}

document.getElementById("list").appendChild(fragment);

Minimize DOM Queries

// Bad - queries DOM multiple times
for (let i = 0; i < 100; i++) {
    document.getElementById("container").appendChild(
        document.createElement("div")
    );
}

// Good - cache reference
const container = document.getElementById("container");
for (let i = 0; i < 100; i++) {
    container.appendChild(document.createElement("div"));
}

Use innerHTML for Large Updates

// Good for large updates
let html = "";
for (let i = 0; i < 1000; i++) {
    html += `<div>Item ${i}</div>`;
}
container.innerHTML = html;

// Avoid for small updates
container.appendChild(document.createElement("div"));

Summary

  • createElement(): create new elements
  • appendChild(): add element as last child
  • insertBefore(): insert before reference element
  • textContent: set/get text
  • innerHTML: set/get HTML
  • setAttribute(): set attributes
  • classList: manage CSS classes
  • style: set inline styles
  • remove(): delete element
  • cloneNode(): duplicate element
  • Best practice: batch updates with DocumentFragment

Official Documentation

Next Steps

  1. Event Delegation and Event Propagation
  2. Event Bubbling and Capturing
  3. Selecting Elements: querySelector, getElementById, etc.

Comments