1. Tổng quan về DOM
DOM (Document Object Model) là giao diện lập trình chuẩn do W3C đề xuất để xử lý các tài liệu HTML/XML. Qua DOM, ta có thể truy cập và thao tác với cấu trúc, nội dung và kiểu dáng của trang web.
- Tài liệu (Document): Mỗi trang web là một tài liệu, được biểu diễn bằng đối tượng
document. - Phần tử (Element): Các thẻ HTML là phần tử, được biểu diễn bằng đối tượng
Element. - Nút (Node): Mọi thứ trong tài liệu (thẻ, thuộc tính, văn bản, chú thích...) đều là nút, được biểu diễn bằng
Node.
Tất cả đều được xem như các đối tượng trong mô hình DOM.
2. Lấy phần tử trong DOM
2.1. Theo ID
const timerEl = document.getElementById('time');
console.log(timerEl);
console.dir(timerEl); // Xem chi tiết thuộc tính/phương thức
2.2. Theo tên thẻ
const listItems = document.getElementsByTagName('li');
console.log(listItems); // Trả về HTMLCollection (giống mảng)
// Duyệt qua từng phần tử
for (let i = 0; i < listItems.length; i++) {
console.log(listItems[i]);
}
// Lấy phần tử con trong một phần tử cha cụ thể
const container = document.getElementById('ftl');
const childItems = container.getElementsByTagName('li');
2.3. Các phương pháp mới từ HTML5
// Theo class
const boxes = document.getElementsByClassName('box');
// Truy vấn CSS selector: trả về phần tử đầu tiên
const firstBox = document.querySelector('.box');
// Truy vấn tất cả phần tử khớp selector
const allBoxes = document.querySelectorAll('.box');
2.4. Truy cập thẻ đặc biệt
const body = document.body;
const html = document.documentElement;
3. Cơ bản về sự kiện (Event)
Sự kiện gồm 3 thành phần:
- Nguồn sự kiện (Event target): Phần tử kích hoạt sự kiện.
- Loại sự kiện (Event type): Ví dụ
click,mouseover. - Hàm xử lý (Event handler): Hàm được gọi khi sự kiện xảy ra.
const btn = document.getElementById('btn');
btn.onclick = function() {
alert('Đã nhấn nút!');
};
4. Thao tác nội dung phần tử
4.1. Thay đổi nội dung văn bản
const div = document.querySelector('div');
div.innerText = 'Nội dung thuần'; // Không hỗ trợ HTML
div.innerHTML = '<strong>Nội dung có HTML</strong>'; // Hỗ trợ HTML
4.2. Cập nhật theo thời gian thực
function getCurrentTime() {
const now = new Date();
const days = ['Chủ nhật', 'Thứ hai', 'Thứ ba', 'Thứ tư', 'Thứ năm', 'Thứ sáu', 'Thứ bảy'];
return `Hôm nay là: ${now.getFullYear()} năm ${now.getMonth() + 1} tháng ${now.getDate()} ngày ${days[now.getDay()]}`;
}
const timeDiv = document.querySelector('div');
timeDiv.innerText = getCurrentTime();
5. Thao tác thuộc tính
5.1. Thuộc tính thông thường
const img = document.querySelector('img');
document.getElementById('zxy').onclick = () => {
img.src = 'images/zxy.jpg';
img.title = 'Trương Học Hữu';
};
5.2. Thuộc tính biểu mẫu
const input = document.querySelector('input');
const button = document.querySelector('button');
button.onclick = function() {
input.value = 'Đã nhấn';
this.disabled = true; // this trỏ đến button
};
5.3. Chuyển đổi loại input (password ↔ text)
const eyeIcon = document.getElementById('eye');
const pwdInput = document.getElementById('password');
let isRevealed = false;
eyeIcon.onclick = () => {
if (!isRevealed) {
pwdInput.type = 'text';
eyeIcon.src = 'images/open.png';
} else {
pwdInput.type = 'password';
eyeIcon.src = 'images/close.png';
}
isRevealed = !isRevealed;
};
6. Thao tác kiểu dáng (Style)
6.1. Qua thuộc tính style
const box = document.querySelector('div');
box.onclick = () => {
box.style.backgroundColor = 'purple';
box.style.width = '500px';
};
6.2. Qua class
const messageEl = document.querySelector('.message');
const passwordField = document.querySelector('#password');
passwordField.onblur = () => {
const len = passwordField.value.length;
if (len < 6 || len > 16) {
messageEl.className = 'message wrong';
messageEl.textContent = 'Mật khẩu phải từ 6–16 ký tự';
} else {
messageEl.className = 'message right';
messageEl.textContent = 'Hợp lệ';
}
};
7. Tư duy loại trừ (Exclusive Selection)
const buttons = document.querySelectorAll('button');
buttons.forEach(btn => {
btn.onclick = function() {
// Bỏ chọn tất cả
buttons.forEach(b => b.style.backgroundColor = '');
// Chọn chính mình
this.style.backgroundColor = 'pink';
};
});
8. Thuộc tính tùy chỉnh
8.1. Cách cổ điển
// Lấy
element.getAttribute('data-id');
// Đặt
element.setAttribute('data-role', 'admin');
// Xóa
element.removeAttribute('data-temp');
8.2. Chuẩn HTML5 (data-*)
// HTML: <div data-user-id="123"></div>
const el = document.querySelector('div');
console.log(el.dataset.userId); // "123"
el.dataset.status = 'active';
9. Thao tác nút (Node)
9.1. Duyệt theo cấp bậc
parentNode: Nút cha gần nhất.children: Mảng chỉ chứa phần tử con (không có text node).firstElementChild/lastElementChild: Phần tử con đầu/cuối.nextElementSibling/previousElementSibling: Anh/chị em liền kề.
9.2. Tạo và chèn nút
const newItem = document.createElement('li');
newItem.textContent = 'Mới';
document.querySelector('ul').appendChild(newItem);
// Chèn trước phần tử khác
const ref = document.querySelector('li:first-child');
document.querySelector('ul').insertBefore(newItem, ref);
9.3. Xóa và sao chép
// Xóa
parent.removeChild(child);
// Sao chép (deep clone)
const clone = originalNode.cloneNode(true);
10. Sự kiện nâng cao
10.1. Đăng ký sự kiện
// Cách truyền thống (chỉ 1 handler)
btn.onclick = handler;
// EventListener (nhiều handler)
btn.addEventListener('click', handler1);
btn.addEventListener('click', handler2);
10.2. Gỡ bỏ sự kiện
// Truyền thống
btn.onclick = null;
// EventListener
btn.removeEventListener('click', handler);
10.3. Luồng sự kiện (Event Flow)
Gồm 3 pha: Capture → Target → Bubble. Mặc định lắng nghe ở pha bubble.
element.addEventListener('click', handler, true); // Capture phase
10.4. Đối tượng sự kiện (Event Object)
e.target: Phần tử thực sự bị click.this: Phần tử được gắn sự kiện.e.type: Loại sự kiện (không có tiền tốon).
10.5. Ngăn hành vi mặc định và nổi bọt
// Ngăn chuyển trang
link.addEventListener('click', e => e.preventDefault());
// Ngăn nổi bọt
child.addEventListener('click', e => e.stopPropagation());
10.6. Ủy quyền sự kiện (Event Delegation)
document.querySelector('ul').addEventListener('click', e => {
if (e.target.tagName === 'LI') {
e.target.style.backgroundColor = 'pink';
}
});
10.7. Sự kiện chuột và bàn phím
// Vô hiệu hóa chuột phải
document.addEventListener('contextmenu', e => e.preventDefault());
// Sự kiện bàn phím
input.addEventListener('keydown', e => {
console.log('Phím nhấn:', e.key, 'Mã ASCII:', e.keyCode);
});