DOM là gì?

DOM (Document Object Model) là một mô hình đối tượng được sử dụng để đại diện cho cấu trúc của tài liệu HTML và XML. Nó giúp các nhà phát triển tương tác với tài liệu web thông qua các ngôn ngữ lập trình như JavaScript. DOM biến các phần tử trong HTML thành các đối tượng mà bạn có thể truy xuất và thay đổi, giúp trang web trở nên động hơn.


1. Cấu trúc cơ bản của DOM

Khi trình duyệt tải một tài liệu HTML, nó tạo ra một cây DOM, trong đó:

  • Document: Đại diện cho toàn bộ tài liệu.
  • Element: Các phần tử HTML như <div>, <p>, <h1>.
  • Text: Nội dung văn bản bên trong các thẻ HTML.

Ví dụ về cấu trúc DOM

<!DOCTYPE html>
<html>
  <head>
    <title>DOM Example</title>
  </head>
  <body>
    <h1>Đây là một tiêu đề</h1>
    <p>Đây là một đoạn văn.</p>
  </body>
</html>

Cấu trúc trên sẽ được trình duyệt tạo thành một cây DOM:

document
  ├── html
      ├── head
      │   └── title
      └── body
          ├── h1
          └── p

2. Cách thao tác cơ bản với DOM

DOM cung cấp nhiều phương thức và thuộc tính giúp bạn truy xuất và thay đổi các phần tử HTML. Đây là một số phương thức phổ biến:

Truy xuất các phần tử DOM

getElementById()

Phương thức này trả về phần tử có id cụ thể.

const element = document.getElementById('myElement');
console.log(element); // Xuất ra phần tử có id 'myElement'

getElementsByClassName()

Lấy tất cả các phần tử có class giống nhau.

const elements = document.getElementsByClassName('myClass');
console.log(elements); // Trả về một danh sách các phần tử có class 'myClass'

querySelector()

Trả về phần tử đầu tiên khớp với một selector CSS.

const element = document.querySelector('.myClass');
console.log(element); // Trả về phần tử đầu tiên có class 'myClass'

querySelectorAll()

Lấy tất cả các phần tử khớp với selector CSS.

const elements = document.querySelectorAll('p.myClass');
console.log(elements); // Trả về tất cả các phần tử <p> có class 'myClass'

3. Thao tác với thuộc tính và nội dung trong DOM

DOM cho phép bạn dễ dàng thay đổi nội dung và thuộc tính của các phần tử HTML.

Thay đổi nội dung văn bản với textContent

Thuộc tính này giúp thay đổi hoặc lấy nội dung văn bản của một phần tử.

const p = document.querySelector('p');
p.textContent = 'Nội dung mới';
console.log(p.textContent); // Hiển thị 'Nội dung mới'

Thay đổi nội dung HTML với innerHTML

Bạn có thể thay đổi hoặc lấy toàn bộ nội dung HTML bên trong một phần tử.

const div = document.querySelector('div');
div.innerHTML = '<p>Nội dung mới</p>';
console.log(div.innerHTML); // Hiển thị '<p>Nội dung mới</p>'

4. Thêm, xóa, sửa các phần tử DOM

Tạo phần tử mới với createElement()

Phương thức này giúp bạn tạo một phần tử HTML mới.

const newDiv = document.createElement('div');
newDiv.textContent = 'Phần tử mới';
document.body.appendChild(newDiv); // Thêm phần tử mới vào body

Xóa phần tử với removeChild()

Bạn có thể xóa một phần tử con khỏi phần tử cha.

const parent = document.querySelector('#parent');
const child = document.querySelector('#child');
parent.removeChild(child); // Xóa phần tử con 'child' khỏi phần tử 'parent'

Thay thế một phần tử với replaceChild()

Thay thế một phần tử cũ bằng một phần tử mới.

const newElement = document.createElement('div');
newElement.textContent = 'Phần tử mới';

const oldElement = document.getElementById('old');
document.body.replaceChild(newElement, oldElement); // Thay thế phần tử 'old'

5. Sự kiện trong DOM (Event)

DOM cung cấp khả năng xử lý sự kiện, cho phép trang web phản hồi khi người dùng tương tác như nhấn chuột, nhập liệu, hoặc di chuyển chuột.

Lắng nghe sự kiện với addEventListener()

Phương thức này cho phép bạn đăng ký một hàm xử lý sự kiện cho một phần tử.

const button = document.querySelector('button');
button.addEventListener('click', function() {
    alert('Button clicked!');
});

Trong ví dụ trên, mỗi khi người dùng nhấn vào nút, một thông báo sẽ xuất hiện.


6. DOM nâng cao

6.1. Virtual DOM

Virtual DOM là một bản sao của DOM thực, giúp tối ưu hóa việc cập nhật giao diện. Thay vì thay đổi trực tiếp DOM thật, Virtual DOM sẽ cập nhật trước, sau đó chỉ thay đổi những phần cần thiết trên DOM thật, giúp cải thiện hiệu suất.

6.2. Shadow DOM

Shadow DOM giúp cô lập các thành phần HTML để chúng không bị ảnh hưởng bởi các phần tử khác trên trang. Đây là một kỹ thuật phổ biến trong Web Components.

<my-element>
  <div>This content is part of the shadow DOM.</div>
</my-element>

6.3. Mutation Observer

MutationObserver cho phép theo dõi các thay đổi trong DOM và xử lý chúng.

const observer = new MutationObserver(function(mutationsList) {
    for(let mutation of mutationsList) {
        console.log(mutation);
    }
});

observer.observe(document.body, { childList: true });

Trong ví dụ này, MutationObserver sẽ theo dõi và ghi lại bất kỳ sự thay đổi nào xảy ra trong danh sách con của body.


7. Tối ưu hóa thao tác với DOM

Giảm thiểu số lần truy xuất DOM

Truy xuất DOM có thể tốn nhiều tài nguyên, vì vậy bạn nên lưu trữ các phần tử đã truy xuất vào biến để tái sử dụng:

const element = document.getElementById('myElement');
// Sử dụng lại biến element thay vì truy xuất DOM nhiều lần

Batch DOM Updates với DocumentFragment

DocumentFragment giúp thêm nhiều phần tử cùng lúc vào DOM mà không gây ra việc render nhiều lần.

const fragment = document.createDocumentFragment();
const newDiv = document.createElement('div');
newDiv.textContent = 'Phần tử mới';
fragment.appendChild(newDiv);
document.body.appendChild(fragment); // Chỉ cập nhật DOM một lần

Kết luận

DOM là một thành phần quan trọng trong lập trình web, cho phép bạn truy xuất, thay đổi, và tương tác với các phần tử HTML. Từ các thao tác cơ bản đến các kỹ thuật nâng cao như Virtual DOM, Shadow DOM và MutationObserver, việc nắm vững DOM sẽ giúp bạn xây dựng các ứng dụng web hiệu quả hơn.