Giới thiệu về BOM
Mô hình Đối tượng Trình duyệt (Browser Object Model - BOM) cung cấp các đối tượng cho phép tương tác với cửa sổ trình duyệt, độc lập với nội dung trang web. Đối tượng trung tâm của BOM là window. Khác với DOM – được tiêu chuẩn hóa bởi W3C – BOM không có chuẩn chính thức, ban đầu được định nghĩa bởi Netscape.
Cấu trúc của BOM
BOM bao gồm nhiều đối tượng con, trong đó window là đối tượng cấp cao nhất. Nó đóng hai vai trò:
- Là giao diện để JavaScript tương tác với cửa sổ trình duyệt.
- Là đối tượng toàn cục: mọi biến và hàm khai báo ở phạm vi toàn cục đều trở thành thuộc tính/phương thức của
window.
Ví dụ minh họa:
<script>
let value = 42;
console.log(value); // 42
console.log(window.value); // 42
function greet() {
console.log("Hello!");
}
greet(); // Gọi trực tiếp
window.greet(); // Gọi qua window
console.log(window.name); // Thuộc tính đặc biệt
</script>
Sự kiện liên quan đến cửa sổ
1. Sự kiện tải trang hoàn chỉnh
window.onload = function() { /* xử lý */ };
// hoặc
window.addEventListener("load", function() { /* xử lý */ });
Sự kiện này kích hoạt khi toàn bộ tài nguyên (HTML, CSS, ảnh, script...) đã tải xong. Lưu ý:
- Dùng
onloadtruyền thống chỉ gán được một lần (ghi đè nếu gán nhiều lần). - Dùng
addEventListenercó thể đăng ký nhiều listener.
2. Sự kiện DOM sẵn sàng
document.addEventListener("DOMContentLoaded", function() { /* xử lý */ });
Kích hoạt ngay khi cây DOM được xây dựng xong, không chờ tải ảnh/CSS. Hỗ trợ từ IE9 trở lên. Phù hợp để khởi tạo giao diện sớm mà không cần đợi toàn bộ tài nguyên.
3. Sự kiện thay đổi kích thước cửa sổ
window.addEventListener("resize", function() {
if (window.innerWidth <= 800) {
document.querySelector("div").style.display = "none";
} else {
document.querySelector("div").style.display = "block";
}
});
Sự kiện này kích hoạt mỗi khi kích thước cửa sổ thay đổi (theo pixel). Thường dùng để xây dựng giao diện responsive.
Hai loại bộ hẹn giờ
1. setTimeout – Thực thi một lần sau thời gian chờ
let timerId = setTimeout(() => {
console.log("Chạy sau 2 giây");
}, 2000);
// Hủy bộ hẹn giờ
clearTimeout(timerId);
Hàm callback được gọi một lần sau khoảng thời gian (tính bằng mili giây). Có thể hủy bằng clearTimeout với ID trả về.
2. setInterval – Lặp lại theo chu kỳ
let countdown = 5;
let intervalId = setInterval(() => {
if (countdown <= 0) {
clearInterval(intervalId);
console.log("Hết giờ!");
} else {
console.log(`Còn lại: ${countdown}s`);
countdown--;
}
}, 1000);
Hàm callback được gọi lặp lại mỗi khoảng thời gian. Dừng bằng clearInterval.
Ví dụ ứng dụng: Đếm ngược đến sự kiện
<div>
<span class="hour">00</span>:
<span class="minute">00</span>:
<span class="second">00</span>
</div>
<script>
const hourEl = document.querySelector(".hour");
const minuteEl = document.querySelector(".minute");
const secondEl = document.querySelector(".second");
const targetTime = new Date("2025-12-31T23:59:59").getTime();
function updateCountdown() {
const now = new Date().getTime();
const diff = targetTime - now;
if (diff <= 0) {
hourEl.textContent = "00";
minuteEl.textContent = "00";
secondEl.textContent = "00";
return;
}
const h = String(Math.floor(diff / (1000 * 60 * 60))).padStart(2, "0");
const m = String(Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60))).padStart(2, "0");
const s = String(Math.floor((diff % (1000 * 60)) / 1000)).padStart(2, "0");
hourEl.textContent = h;
minuteEl.textContent = m;
secondEl.textContent = s;
}
updateCountdown(); // Gọi ngay để tránh trống lúc load
setInterval(updateCountdown, 1000);
</script>
Ví dụ: Nút gửi mã OTP bị khóa 60 giây
<button id="sendBtn">Gửi mã</button>
<script>
const btn = document.getElementById("sendBtn");
btn.addEventListener("click", () => {
let seconds = 60;
btn.disabled = true;
btn.textContent = `Chờ ${seconds}s`;
const timer = setInterval(() => {
seconds--;
if (seconds <= 0) {
clearInterval(timer);
btn.disabled = false;
btn.textContent = "Gửi mã";
} else {
btn.textContent = `Chờ ${seconds}s`;
}
}, 1000);
});
</script>
Đối tượng location
Thuộc tính window.location chứa thông tin URL hiện tại và cho phép điều hướng.
Thuộc tính quan trọng
href: Toàn bộ URL.search: Chuỗi query string (phần sau dấu?).
Phương thức điều hướng
// Chuyển hướng và lưu vào lịch sử
location.assign("https://example.com");
// Chuyển hướng KHÔNG lưu lịch sử
location.replace("https://example.com");
// Tải lại trang
location.reload(); // Từ cache
location.reload(true); // Từ server
Đối tượng navigator
Chứa thông tin về trình duyệt. Thường dùng navigator.userAgent để phát hiện thiết bị:
const isMobile = /Android|iPhone|iPad|iPod|BlackBerry|Windows Phone/i.test(navigator.userAgent);
if (isMobile) {
window.location.href = "/mobile.html";
}
Đối tượng history
Cho phép tương tác với lịch sử duyệt web:
// Quay lại trang trước
history.back();
// Tiến tới trang tiếp
history.forward();
// Di chuyển n bước (âm: lùi, dương: tiến)
history.go(-1); // tương đương back()
history.go(1); // tương đương forward()