BOM (Browser Object Model)
BOM — набор объектов, предоставляемых браузером для взаимодействия с окном браузера и его окружением. Главный объект —
window.
Зачем нужно
BOM позволяет управлять браузером из JavaScript: перенаправлять пользователя, получать информацию об устройстве и браузере, работать с историей навигации, определять размеры экрана и окна.
Где используется
- Редиректы и навигация
- Определение устройства и браузера
- Управление историей (SPA-роутинг)
- Таймеры и диалоговые окна
- Адаптивная логика на основе размеров экрана
Предпосылки
Введение в JavaScript, DOM дерево
window — глобальный объект
// window — верхний объект в браузере
// Все глобальные переменные (var) и функции становятся свойствами window
var greeting = 'Привет';
console.log(window.greeting); // 'Привет'
// let и const НЕ попадают в window
let x = 10;
console.log(window.x); // undefined
// Размеры окна
window.innerWidth; // ширина области содержимого (включая scrollbar)
window.innerHeight; // высота области содержимого
window.outerWidth; // ширина всего окна браузера
window.outerHeight; // высота всего окна браузера
// Позиция прокрутки
window.scrollX; // горизонтальная прокрутка (pageXOffset)
window.scrollY; // вертикальная прокрутка (pageYOffset)
// Прокрутка
window.scrollTo(0, 500); // абсолютная
window.scrollBy(0, 100); // относительная
window.scrollTo({ top: 500, behavior: 'smooth' }); // плавная
navigator — информация о браузере
// User-Agent строка
console.log(navigator.userAgent);
// "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36..."
// Язык
console.log(navigator.language); // "ru-RU"
console.log(navigator.languages); // ["ru-RU", "ru", "en-US", "en"]
// Сеть
console.log(navigator.onLine); // true/false
window.addEventListener('online', () => console.log('Снова онлайн'));
window.addEventListener('offline', () => console.log('Нет сети'));
// Платформа
console.log(navigator.platform); // "Win32", "MacIntel", "Linux x86_64"
// Буфер обмена (async)
await navigator.clipboard.writeText('Скопировано!');
const text = await navigator.clipboard.readText;
// Геолокация
navigator.geolocation.getCurrentPosition(
(pos) => console.log(pos.coords.latitude, pos.coords.longitude),
(err) => console.error(err.message)
);
// User-Agent Client Hints (современный подход)
const ua = navigator.userAgentData;
console.log(ua?.platform); // "Windows"
console.log(ua?.mobile); // false
location — URL и навигация
// Текущий URL: https://example.com:8080/path/page?q=js#section
console.log(location.href); // полный URL
console.log(location.protocol); // "https:"
console.log(location.host); // "example.com:8080"
console.log(location.hostname); // "example.com"
console.log(location.port); // "8080"
console.log(location.pathname); // "/path/page"
console.log(location.search); // "?q=js"
console.log(location.hash); // "#section"
console.log(location.origin); // "https://example.com:8080"
// Навигация
location.href = 'https://google.com'; // перенаправление (в историю)
location.assign('https://google.com'); // то же самое
location.replace('https://google.com'); // без записи в историю
location.reload; // перезагрузка страницы
// Разбор query-параметров
const params = new URLSearchParams(location.search);
console.log(params.get('q')); // "js"
params.set('page', '2');
console.log(params.toString()); // "q=js&page=2"
history — история навигации
// Навигация по истории
history.back; // назад (аналог кнопки «Назад»)
history.forward; // вперёд
history.go(-2); // на 2 шага назад
history.go(1); // на 1 шаг вперёд
console.log(history.length); // количество записей в истории
// pushState и replaceState — SPA-роутинг без перезагрузки
history.pushState(
{ page: 'about' }, // state-объект
'', // title (обычно игнорируется)
'/about' // новый URL
);
history.replaceState({ page: 'home' }, '', '/home');
// Событие popstate — срабатывает при back/forward
window.addEventListener('popstate', (event) => {
console.log('Навигация:', event.state);
// { page: 'about' }
});
screen — информация об экране
console.log(screen.width); // полная ширина экрана (px)
console.log(screen.height); // полная высота экрана
console.log(screen.availWidth); // доступная ширина (без панели задач)
console.log(screen.availHeight); // доступная высота
console.log(screen.colorDepth); // глубина цвета (обычно 24)
console.log(screen.pixelDepth); // глубина пикселя
// Ориентация экрана (мобильные)
console.log(screen.orientation?.type); // "portrait-primary"
screen.orientation?.addEventListener('change', () => {
console.log('Ориентация:', screen.orientation.type);
});
Диалоговые окна
// alert — простое сообщение (блокирует поток)
alert('Внимание!');
// confirm — подтверждение (возвращает boolean)
const agreed = confirm('Вы согласны?');
console.log(agreed); // true или false
// prompt — ввод текста (возвращает string или null)
const name = prompt('Как вас зовут?', 'Аноним');
console.log(name); // введённый текст или null (при отмене)
// В продакшене используйте кастомные модальные окна!
// alert/confirm/prompt блокируют поток и выглядят некрасиво
Таймеры
// setTimeout — однократное выполнение
const timerId = setTimeout(() => {
console.log('Через 2 секунды');
}, 2000);
clearTimeout(timerId); // отмена
// setInterval — повторное выполнение
const intervalId = setInterval(() => {
console.log('Каждую секунду');
}, 1000);
clearInterval(intervalId); // остановка
// requestAnimationFrame — для анимаций (≈60fps)
function animate() {
// логика анимации
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
Частые ошибки
1. Определение браузера через userAgent
// Плохо — userAgent ненадёжен и может быть подделан
if (navigator.userAgent.includes('Chrome')) {
// Может быть Edge, Opera или другой Chromium-браузер
}
// Лучше — feature detection
if ('IntersectionObserver' in window) {
// Браузер поддерживает IntersectionObserver
}
2. location.href vs location.replace
// href и assign — добавляют запись в историю
location.href = '/login'; // пользователь сможет нажать «Назад»
// replace — НЕ добавляет в историю
location.replace('/login'); // кнопка «Назад» не вернёт на предыдущую страницу
// Используйте replace для редиректов после авторизации
3. Забытый clearInterval
// Утечка памяти: интервал работает вечно
setInterval(() => {
const el = document.querySelector('#status');
if (el) el.textContent = new Date.toLocaleTimeString();
}, 1000);
// Правильно: сохраняем ID и очищаем
const id = setInterval(() => {
const el = document.querySelector('#status');
if (!el) {
clearInterval(id); // элемент удалён — останавливаем
return;
}
el.textContent = new Date.toLocaleTimeString();
}, 1000);
Практика
- Выведи в консоль все свойства
locationдля текущей страницы - Реализуй простой SPA-роутер с
pushStateиpopstate - Определи, онлайн или оффлайн пользователь, и покажи уведомление
- Используй
screenиwindow.innerWidthдля адаптивной логики