Nguyễn Đình Cường
0 comment
09 Nov, 2026
Khi trình duyệt tải một trang HTML, nó biến nội dung thành một cây đối tượng gọi là DOM (Document Object Model). JavaScript dùng DOM để đọc và thay đổi trang: đổi chữ, thêm phần tử, bật tắt class, phản hồi cú nhấp chuột. Đây là kỹ năng nền tảng trước khi bạn học các framework như React hay Vue.
Hai phương thức hiện đại và linh hoạt nhất là:
const tieuDe = document.querySelector('h1'); // phần tử đầu tiên khớp
const nut = document.querySelector('#gui'); // theo id
const cacThe = document.querySelectorAll('.card'); // tất cả phần tử khớpChúng nhận selector CSS giống hệt bạn dùng trong file CSS. querySelector trả về phần tử hoặc null nếu không thấy, còn querySelectorAll trả về NodeList, có thể duyệt bằng forEach hoặc for...of. Nếu cần các phương thức mảng như map, hãy chuyển bằng Array.from(cacThe). Nhớ kiểm tra null trước khi dùng, vì nếu script chạy trước khi phần tử tồn tại bạn sẽ gặp lỗi.
tieuDe.textContent = 'Xin chào, DOM!'; // đặt chữ thuần
console.log(tieuDe.textContent); // đọc chữ
const link = document.querySelector('a');
link.setAttribute('href', 'https://codebem.com');
console.log(link.getAttribute('href'));Có hai cách đặt nội dung: textContent xem mọi thứ là chữ thuần, an toàn. innerHTML hiểu chuỗi là HTML, tiện nhưng nguy hiểm nếu chuỗi chứa dữ liệu từ người dùng vì có thể bị chèn mã độc (XSS). Quy tắc: dùng textContent trừ khi bạn thực sự cần HTML và chắc chắn nó đáng tin.
Thay vì sửa từng thuộc tính style, hãy bật tắt class đã định nghĩa trong CSS:
const hop = document.querySelector('.menu');
hop.classList.add('open');
hop.classList.remove('open');
hop.classList.toggle('open'); // bật nếu chưa có, tắt nếu có
console.log(hop.classList.contains('open'));Cách này giữ việc "trông thế nào" trong CSS và "khi nào" trong JavaScript, mã dễ bảo trì hơn nhiều.
const ul = document.querySelector('#danh-sach');
const monAn = ['Phở', 'Bún chả', 'Cơm tấm'];
monAn.forEach(function (ten) {
const li = document.createElement('li');
li.textContent = ten;
li.classList.add('mon');
ul.appendChild(li);
});Một số phương thức chèn khác: append và prepend chèn vào cuối hoặc đầu, before và after chèn cạnh phần tử, remove() xóa phần tử, cloneNode(true) sao chép phần tử cùng nội dung con. Khi chèn nhiều phần tử, bạn có thể gom chúng vào một DocumentFragment rồi chèn một lần để giảm số lần trình duyệt phải vẽ lại.
Từ một phần tử bạn có thể đi đến các phần tử liên quan:
parentElement: phần tử cha.children: các phần tử con.nextElementSibling và previousElementSibling: anh em kế tiếp và liền trước.closest('.card'): tổ tiên gần nhất khớp selector, rất hữu ích khi xử lý sự kiện.Nếu thẻ script đặt trong head và chạy trước khi body được tạo, querySelector sẽ trả về null. Có ba cách an toàn: đặt script cuối body, dùng thuộc tính defer trên thẻ script, hoặc đặt mã trong sự kiện DOMContentLoaded:
document.addEventListener('DOMContentLoaded', function () {
console.log('Trang đã sẵn sàng');
});querySelector nhiều lần trong vòng lặp.Hãy ghép các kiến thức trên thành một tính năng nhỏ nhưng hữu dụng. Giả sử CSS đã định nghĩa các biến màu cho [data-theme='dark']:
const nut = document.querySelector('#doi-giao-dien');
const goc = document.documentElement;
nut.addEventListener('click', function () {
const dangToi = goc.getAttribute('data-theme') === 'dark';
goc.setAttribute('data-theme', dangToi ? 'light' : 'dark');
nut.textContent = dangToi ? 'Chế độ tối' : 'Chế độ sáng';
});Chỉ với vài dòng, bạn đã đọc thuộc tính, ghi thuộc tính và đổi chữ nút. Hãy thử mở rộng bằng cách lưu lựa chọn vào localStorage để lần sau người dùng quay lại vẫn giữ giao diện họ đã chọn.
querySelector('gui'), nên selector hiểu là thẻ gui và trả về null.innerHTML += trong vòng lặp để thêm từng mục: mỗi lần nó dựng lại toàn bộ nội dung bên trong, làm mất trình lắng nghe sự kiện gắn trên các phần tử cũ và chậm khi danh sách dài.value của ô nhập và textContent của các thẻ thông thường.Khi gặp lỗi, hãy kiểm tra giá trị trả về của querySelector trong Console trước tiên, vì phần lớn lỗi bắt nguồn từ việc chọn sai hoặc chọn quá sớm.
Với querySelector, textContent, classList và createElement, bạn đã làm được phần lớn các tương tác cơ bản. Hãy thử tự làm một danh sách công việc nhỏ để luyện tập. Các framework về sau chỉ là cách tự động hóa những thao tác này.
Nếu cần một lộ trình từ DOM đến ứng dụng web hoàn chỉnh, bạn có thể xem các khóa học của codebem.com.
Nguyễn Đình Cường
0 comment