Перейти к основному содержимому

Объектная модель браузера (BOM)

Разработчику Архитектору

DOM и BOM

DOM описывает документ — узлы HTML на странице (работа с HTML).

BOM (Browser Object Model) описывает окружение браузера — окно, адресная строка, история переходов, данные об устройстве, размеры viewport. Корневой объект — window; в браузере глобальные переменные и функции (alert, setTimeout) живут в его области видимости.

console.log(window === globalThis); // true в современных браузерах

Разбор:

  • В этом фрагменте используется конструкция console.log(window === globalThis); // true в современных браузерах как точка входа сценария.
  • Код показывает последовательность действий: получение данных, проверка условий и выполнение целевого действия.
  • Ключевые вызовы и свойства опираются на стандартные API JavaScript/браузера, поэтому шаблон легко перенести в реальный проект.
  • Такой пример удобно расширять обработкой ошибок, логированием и дополнительной валидацией входных данных.

В Node.js вместо windowglobal / globalThis; DOM и BOM там нет.


Модель BOM: что запомнить

BOM — API окна вкладки, не DOM-дерева страницы. Три опоры:

  • Где пользовательlocation, параметры URL.
  • Как попал и куда может вернутьсяhistory.
  • Средаnavigator, размеры окна, сеть (onLine, Connection API).

С этой схемой проще связать API с маршрутизацией и адаптивным UI.


Объект location

window.location (и сокращение document.location) отражает URL текущей страницы.

Свойство / методНазначение
hrefполный URL
pathnameпуть без домена (/catalog/item)
searchстрока запроса (?id=5)
hashфрагмент (#reviews)
assign(url)переход с записью в history
replace(url)переход без новой записи в history
reload()перезагрузка страницы
const params = new URLSearchParams(location.search);
const id = params.get('id');

if (!id) {
location.assign('/catalog');
}

Разбор:

  • В этом фрагменте используется конструкция const params = new URLSearchParams(location.search); как точка входа сценария.
  • Код показывает последовательность действий: получение данных, проверка условий и выполнение целевого действия.
  • Ключевые вызовы и свойства опираются на стандартные API JavaScript/браузера, поэтому шаблон легко перенести в реальный проект.
  • Такой пример удобно расширять обработкой ошибок, логированием и дополнительной валидацией входных данных.

Чтение location без присваивания безопасно; location.href = '...' и location.assign() инициируют навигацию. Для SPA чаще меняют маршрут через History API или роутер фреймворка, не полную перезагрузку.


Объект history

window.history хранит стек переходов в рамках одного источника (origin).

МетодДействие
back()шаг назад
forward()шаг вперёд
go(n)на n шагов (-1 — назад)
pushState(state, title, url?)добавить запись без перезагрузки
replaceState(state, title, url?)заменить текущую запись
history.pushState({ page: 'settings' }, '', '/app/settings');

window.addEventListener('popstate', (event) => {
console.log('Навигация назад/вперёд', event.state);
});

Разбор:

  • В этом фрагменте используется конструкция history.pushState({ page: 'settings' }, '', '/app/settings'); как точка входа сценария.
  • Код показывает последовательность действий: получение данных, проверка условий и выполнение целевого действия.
  • Подписка через addEventListener связывает поведение с действием пользователя и отделяет логику от HTML-разметки.
  • Ключевые вызовы и свойства опираются на стандартные API JavaScript/браузера, поэтому шаблон легко перенести в реальный проект.
  • Такой пример удобно расширять обработкой ошибок, логированием и дополнительной валидацией входных данных.

Событие popstate срабатывает при кнопках "назад/вперёд", не при pushState из скрипта. Данные state — произвольный сериализуемый объект; не кладите туда секреты.


Объект navigator

navigator — сведения о браузере и возможностях устройства.

Свойство / APIТипичное использование
userAgentстрока клиента (осторожно: подделывается, не для жёсткой логики)
language / languagesпредпочитаемые языки интерфейса
onLineесть ли сеть (грубая оценка)
clipboardClipboard API — копирование текста
shareWeb Share API — системное окно "Поделиться" (title, text, url)
serviceWorkerрегистрация фонового скрипта (PWA)
mediaDevicesкамера/микрофон (WebRTC)
if (!navigator.onLine) {
showBanner('Нет подключения — часть функций недоступна');
}

Разбор:

  • В этом фрагменте используется конструкция if (!navigator.onLine) { как точка входа сценария.
  • Код показывает последовательность действий: получение данных, проверка условий и выполнение целевого действия.
  • Ключевые вызовы и свойства опираются на стандартные API JavaScript/браузера, поэтому шаблон легко перенести в реальный проект.
  • Такой пример удобно расширять обработкой ошибок, логированием и дополнительной валидацией входных данных.

Проверка возможностей — 'geolocation' in navigator, 'serviceWorker' in navigator — надёжнее, чем разбор userAgent.


Геолокация — navigator.geolocation

Geolocation API возвращает координаты устройства (GPS, Wi‑Fi, IP). Доступ только по HTTPS (или localhost) и с разрешения пользователя.

Код ITЗагрузка примера кода…

МетодНазначение
getCurrentPosition(success, error?, options?)координаты один раз
watchPosition(success, error?, options?)подписка на изменение; возвращает id
clearWatch(id)отменить watchPosition

Обёртка в Promise удобна с async/await:

function getPosition(options) {
return new Promise((resolve, reject) => {
navigator.geolocation.getCurrentPosition(resolve, reject, options);
});
}

const pos = await getPosition({ timeout: 5000 });

Координаты не подставляйте в URL без согласия пользователя; на сервере всё равно нужна серверная валидация адреса.


Хранение данных на клиенте

BOM и DOM дают несколько уровней хранения:

APIГдеКратко
document.cookieстрока с параметрамисессии, совместимость; HttpOnly — только сервер
localStorage / sessionStorageключ–значение, ~5 МБнастройки UI, черновики
IndexedDBобъекты, большие объёмыофлайн-кэш, файлы

Подробное сравнение, лимиты и риски XSS — в хранении данных в браузере. Cookie для авторизации предпочтительнее localStorage.


Размеры окна и прокрутка

APIЧто измеряет
window.innerWidth / innerHeightviewport с полосами прокрутки
window.outerWidth / outerHeightвсё окно браузера с рамками
document.documentElement.clientWidthширина области просмотра <html>
window.scrollX, window.scrollYсмещение прокрутки страницы
window.scrollTo(x, y)программная прокрутка
element.scrollIntoView()прокрутить к элементу
window.addEventListener('scroll', () => {
const scrolled = window.scrollY;
document.body.classList.toggle('header--compact', scrolled > 80);
}, { passive: true });

Разбор:

  • В этом фрагменте используется конструкция window.addEventListener('scroll', () => { как точка входа сценария.
  • Код показывает последовательность действий: получение данных, проверка условий и выполнение целевого действия.
  • Подписка через addEventListener связывает поведение с действием пользователя и отделяет логику от HTML-разметки.
  • Ключевые вызовы и свойства опираются на стандартные API JavaScript/браузера, поэтому шаблон легко перенести в реальный проект.
  • Такой пример удобно расширять обработкой ошибок, логированием и дополнительной валидацией входных данных.

Флаг passive: true на scroll/touch подсказывает браузеру, что вы не вызовете preventDefault() — прокрутка остаётся плавной.

Размеры конкретного блока на странице — через getBoundingClientRect() и ResizeObserver, не через window.


screen, open и диалоги

window.screen — физический экран (width, height, availWidth). Нужен редко (полноэкранные режимы, аналитика).

window.open(url, target, features) — новое окно или вкладка. Всплывающие окна часто блокируются, если вызов не из прямого действия пользователя (клик).

alert, confirm, prompt — синхронные диалоги, блокируют главный поток. В продакшене UI лучше строить через разметку и модальные компоненты; нативные диалоги оставляют для отладки и простых учебных примеров.


События жизненного цикла страницы

СобытиеКогда
DOMContentLoadedDOM построен, без ожидания картинок
loadзагружены ресурсы (включая изображения)
beforeunloadуход со страницы (можно показать предупреждение)
resizeизменился размер окна
hashchangeизменился #фрагмент в URL

Инициализацию скриптов, которым нужен готовый DOM, удобно вешать на DOMContentLoaded — см. подключение кода.


Практические правила

  • Не смешивайте полную перезагрузку (location.href = …) и SPA-навигацию без понимания, что history и состояние приложения сбросятся.
  • Не полагайтесь на userAgent для ветвления логики — используйте feature detection.
  • Тяжёлую работу на scroll дебаунсьте или заменяйте IntersectionObserver.
  • Секреты и токены не храните в history.state и не передавайте в hash без необходимости.

Мини-паттерны из продакшена

ЗадачаBOM APIПримечание
Восстановить фильтр каталога после reloadlocation.search + URLSearchParamsлегко поделиться ссылкой с параметрами
Сделать кнопку "Назад к списку" в SPAhistory.pushState и popstateважно хранить минимальный state
Показать баннер offlinenavigator.onLine + online/offline событиястатус сети служит UX-подсказкой
Фиксировать шапку после прокруткиscrollY + passive listenerтяжёлые вычисления выносить в requestAnimationFrame

Эти паттерны помогают строить навигацию и поведение страницы предсказуемо, особенно в связке с событиями и структурой модулей.


Разделение ответственности

Такое разделение ускоряет отладку: источник проблемы находится быстрее, и код становится проще поддерживать в долгую.


Краткий итог

BOM — это window и связанные объекты location, history, navigator, API прокрутки и размеров. DOM меняет страницу; BOM — контекст, в котором страница открыта. Для интерактивности внутри документа сочетайте BOM с событиями и DOM.