← Quay lại Blog

DOM Manipulation Trong JavaScript

DOM Manipulation Trong JavaScript

DOM (Document Object Model) là biểu diễn cấu trúc HTML của trang web. JavaScript cho phép bạn thao tác với DOM để tạo ra các trang web động và tương tác.

Lấy Elements

getElementById

1
2
const element = document.getElementById('myId');
console.log(element);

querySelector và querySelectorAll

1
2
3
4
5
6
7
// Lấy element đầu tiên
const firstDiv = document.querySelector('.my-class');
const firstButton = document.querySelector('button');

// Lấy tất cả elements
const allDivs = document.querySelectorAll('.my-class');
const allButtons = document.querySelectorAll('button');

getElementsByClassName và getElementsByTagName

1
2
const elements = document.getElementsByClassName('my-class');
const divs = document.getElementsByTagName('div');

Tạo Elements

1
2
3
4
5
6
7
8
// Tạo element mới
const newDiv = document.createElement('div');
newDiv.textContent = 'Nội dung mới';
newDiv.className = 'my-class';
newDiv.id = 'new-id';

// Thêm vào DOM
document.body.appendChild(newDiv);

Tạo Element với Attributes

1
2
3
4
5
6
7
const link = document.createElement('a');
link.href = 'https://example.com';
link.textContent = 'Click me';
link.target = '_blank';
link.setAttribute('data-id', '123');

document.body.appendChild(link);

Thêm và Xóa Elements

appendChild và insertBefore

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
const parent = document.getElementById('parent');
const newElement = document.createElement('div');
newElement.textContent = 'Element mới';

// Thêm vào cuối
parent.appendChild(newElement);

// Thêm vào trước element khác
const existingElement = document.getElementById('existing');
parent.insertBefore(newElement, existingElement);

removeChild và remove

1
2
3
4
5
6
7
8
const parent = document.getElementById('parent');
const child = document.getElementById('child');

// Cách 1: Sử dụng removeChild
parent.removeChild(child);

// Cách 2: Sử dụng remove (hiện đại hơn)
child.remove();

replaceChild

1
2
3
4
5
6
const parent = document.getElementById('parent');
const oldElement = document.getElementById('old');
const newElement = document.createElement('div');
newElement.textContent = 'Element mới';

parent.replaceChild(newElement, oldElement);

Thay Đổi Nội Dung

textContent và innerHTML

1
2
3
4
5
6
7
const element = document.getElementById('myElement');

// textContent - chỉ text, an toàn hơn
element.textContent = 'Nội dung mới';

// innerHTML - cho phép HTML, cẩn thận với XSS
element.innerHTML = '<strong>Nội dung</strong> với <em>HTML</em>';

innerText vs textContent

1
2
3
4
5
// textContent - lấy tất cả text, kể cả ẩn
const text1 = element.textContent;

// innerText - chỉ lấy text hiển thị
const text2 = element.innerText;

Thay Đổi Attributes và Styles

Attributes

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
const element = document.getElementById('myElement');

// Đọc attribute
const id = element.getAttribute('id');
const dataValue = element.getAttribute('data-value');

// Ghi attribute
element.setAttribute('class', 'new-class');
element.setAttribute('data-id', '123');

// Xóa attribute
element.removeAttribute('data-id');

// Đọc/ghi thuộc tính trực tiếp
element.id = 'new-id';
element.className = 'new-class';

Styles

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const element = document.getElementById('myElement');

// Thay đổi style trực tiếp
element.style.color = 'red';
element.style.backgroundColor = 'blue';
element.style.fontSize = '20px';
element.style.display = 'none';

// Thêm/xóa class
element.classList.add('active');
element.classList.remove('inactive');
element.classList.toggle('highlight');
element.classList.replace('old-class', 'new-class');

// Kiểm tra class
if (element.classList.contains('active')) {
    console.log('Element có class active');
}

Xử Lý Events

addEventListener

1
2
3
4
5
6
7
const button = document.getElementById('myButton');

button.addEventListener('click', function(event) {
    console.log('Button được click!');
    console.log('Event:', event);
    console.log('Target:', event.target);
});

Event Delegation

1
2
3
4
5
6
7
8
// Thay vì thêm listener cho từng button
const container = document.getElementById('container');

container.addEventListener('click', function(event) {
    if (event.target.classList.contains('button')) {
        console.log('Button được click:', event.target.textContent);
    }
});

Các Events Phổ Biến

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
const element = document.getElementById('myElement');

// Click
element.addEventListener('click', handleClick);

// Mouse events
element.addEventListener('mouseenter', () => console.log('Mouse enter'));
element.addEventListener('mouseleave', () => console.log('Mouse leave'));
element.addEventListener('mousemove', (e) => console.log('Mouse move', e.clientX, e.clientY));

// Keyboard events
document.addEventListener('keydown', (e) => {
    console.log('Key pressed:', e.key);
    if (e.key === 'Enter') {
        console.log('Enter được nhấn');
    }
});

// Form events
const form = document.getElementById('myForm');
form.addEventListener('submit', (e) => {
    e.preventDefault(); // Ngăn submit mặc định
    console.log('Form submitted');
});

// Input events
const input = document.getElementById('myInput');
input.addEventListener('input', (e) => {
    console.log('Input value:', e.target.value);
});

Traversing DOM

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
const element = document.getElementById('myElement');

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

// Children
const firstChild = element.firstElementChild;
const lastChild = element.lastElementChild;
const children = element.children;

// Siblings
const nextSibling = element.nextElementSibling;
const previousSibling = element.previousElementSibling;

// Tất cả siblings
const siblings = Array.from(element.parentElement.children)
    .filter(child => child !== element);

Ví Dụ Thực Tế: Tạo Todo List

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// HTML: <ul id="todoList"></ul>

const todoList = document.getElementById('todoList');
const input = document.getElementById('todoInput');
const addButton = document.getElementById('addButton');

function addTodo() {
    const text = input.value.trim();
    if (text === '') return;
    
    // Tạo li element
    const li = document.createElement('li');
    li.className = 'todo-item';
    
    // Tạo span cho text
    const span = document.createElement('span');
    span.textContent = text;
    
    // Tạo button xóa
    const deleteBtn = document.createElement('button');
    deleteBtn.textContent = 'Xóa';
    deleteBtn.addEventListener('click', () => {
        li.remove();
    });
    
    // Thêm vào DOM
    li.appendChild(span);
    li.appendChild(deleteBtn);
    todoList.appendChild(li);
    
    // Xóa input
    input.value = '';
}

addButton.addEventListener('click', addTodo);
input.addEventListener('keypress', (e) => {
    if (e.key === 'Enter') {
        addTodo();
    }
});

Tối Ưu Hiệu Suất

1. Sử dụng DocumentFragment

1
2
3
4
5
6
7
8
9
const fragment = document.createDocumentFragment();

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

document.body.appendChild(fragment); // Chỉ reflow một lần

2. Batch DOM Updates

1
2
3
4
5
6
7
// ❌ Bad - Nhiều reflow
element.style.width = '100px';
element.style.height = '100px';
element.style.backgroundColor = 'red';

// ✅ Good - Một reflow
element.style.cssText = 'width: 100px; height: 100px; background-color: red;';

3. Debounce và Throttle

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
function debounce(func, wait) {
    let timeout;
    return function executedFunction(...args) {
        const later = () => {
            clearTimeout(timeout);
            func(...args);
        };
        clearTimeout(timeout);
        timeout = setTimeout(later, wait);
    };
}

const handleScroll = debounce(() => {
    console.log('Scrolling...');
}, 200);

window.addEventListener('scroll', handleScroll);

Kết Luận

DOM Manipulation là kỹ năng cơ bản nhưng mạnh mẽ trong JavaScript. Hiểu rõ cách thao tác với DOM giúp bạn tạo ra các trang web tương tác và động. Trong lập trình mạng, DOM thường được sử dụng để hiển thị dữ liệu từ API, cập nhật giao diện real-time, và xử lý user interactions.