Кратко
СкопированоСовременный JavaScript используется не только в браузерах. Среда, в которой он запускается, будь то браузер, сервер или что-то ещё, называется окружением.
У разных окружений разные возможности и функциональность. В этой статье рассмотрим браузерное окружение и браузерную модель документа.
Окружение предоставляет языку дополнительные возможности и функции. Браузерное окружение, например, даёт возможность работать со страницами сайтов.
Представление этих дополнительных возможностей и функциональности в виде объектов, к которым у языка есть доступ — это объектная модель.
В случае с браузерным окружением — это объектная модель браузера (Browser Object Model, BOM). Она предоставляет доступ к navigator
, location
, fetch
и другим объектам.
/* BOM | __________________________|______________________________________ | | | | | |navigator screen location fetch history ...*/
/* BOM | __________________________|______________________________________ | | | | | | navigator screen location fetch history ... */
Объект navigator
содержит информацию о браузере: название, версия, платформа, доступные плагины, доступ к буферу обмена и прочее. Это один из самых больших объектов в окружении.
Так, например, может выглядеть содержимое этого объекта в Safari:
Или, например, так в Chrome:
С помощью этого объекта можно узнать, разрешён ли доступ к кукам, получить доступ к буферу обмена, геолокации, узнать, с какого браузера пользователь смотрит на страницу через user
.
Забавный факт: поле user
объекта navigator
часто используется, чтобы определять, в каком именно браузере пользователь смотрит страницу сайта. Но читать его глазами достаточно трудно, поэтому лучше это дело оставить какому-нибудь парсеру.
Также с помощью navigator
можно зарегистрировать Service Worker.
screen
СкопированоОбъект screen
содержит информацию об экране браузера.
width
и height
указывают ширину и высоту экрана в пикселях соответственно. avail
метрики указывают, сколько ширины и высоты доступно — то есть ширину и высоту с учётом интерфейсных деталей браузера типа полос прокрутки.
pixel
указывает количество битов на один пиксель экрана.
location
СкопированоОбъект location
даёт возможность узнать, на какой странице мы находимся (какой у неё URL) и перейти на другую страницу программно.
Например, для страницы https://www.google.com?search?sxsrf=ALekK02Nk... этот объект будет содержать:
Внутри него есть полезные поля для того, чтобы искать нужную часть адреса.
href
содержит URL целиком, включая в себя полный адрес хоста, страницы и все query-параметры.host
иhostname
указывают имя хоста. Разница между ними в том, чтоhost
включает в себя порт. Если бы мы стучались не на[google
, а на. com ] ( http : / / google . com ) google
, то. com : 8080 host
содержал бы значениеwww
, в то время как. google . com : 8080 hostname
остался бы тем же.pathname
указывает путь от корня адреса до текущей страницы.search
указывает query-параметры, которые находятся в адресной строке, если они есть.hash
указывает хеш (ID элемента после#
) страницы. Его ещё называют якорем, потому что при переходе на страницу с хешем браузер найдёт элемент с ID, равным этому хешу, и прокрутит страницу к этому элементу.
Если мы хотим изменить адрес и перейти на другую страницу, мы можем указать новый location
:
location.href = 'https://yandex.ru'
location.href = 'https://yandex.ru'
И браузер перейдёт на страницу с адресом https://yandex.ru.
fetch
Скопированоfetch
предоставляет возможность работы с сетью, с его помощью можно отправлять запросы на сервер.
fetch('http://example.com/movies.json') .then((response) => { return response.json() }) .then((data) => { console.log(data) })
fetch('http://example.com/movies.json') .then((response) => { return response.json() }) .then((data) => { console.log(data) })
history
Скопированоhistory
даёт доступ к истории браузера, которая ограничена текущей вкладкой. То есть с её помощью можно перейти на страницу назад, только если мы пришли с неё.
Чтобы перемещаться по истории назад и вперёд, можно использовать методы back
и forward
:
// Перешли на страницу назадhistory.back()// Перешли на страницу вперёдhistory.forward()
// Перешли на страницу назад history.back() // Перешли на страницу вперёд history.forward()
Для более точного управления историей рекомендуется использовать push
и replace
.
Методы push
и replace
принимают три параметра:
state
— любые данные, которые связаны с переходом;unused
— неиспользуемый параметр, который существует по историческим причинам;url
(необязательный) — url адрес новой записи в истории.
// state — данные для новой записи в историиconst state = { user_id: 5 }// unused — для совместимости рекомендуется передавать пустую строкуconst unused = ''// url — url адрес который будет добавлен в адресную строкуconst url = '/another-page/'history.pushState(state, unused, url)
// state — данные для новой записи в истории const state = { user_id: 5 } // unused — для совместимости рекомендуется передавать пустую строку const unused = '' // url — url адрес который будет добавлен в адресную строку const url = '/another-page/' history.pushState(state, unused, url)
Браузер «перейдёт» на страницу /another
. Перейдёт не по-настоящему, потому что страница не перезагрузится, а лишь сменит адрес в строке. Это удобно при работе с одностраничными приложениями, когда мы не хотим, чтобы страница перезагружалась.
localStorage
, sessionStorage
СкопированоЛокальные хранилища используются, чтобы хранить какие-то данные в браузере пользователя.
Они удобны, когда мы не хотим отправлять данные на сервер, потому что они, например, промежуточные, или нужны только на клиенте.
Допустим, у нас есть форма из 5 шагов, и мы хотим, чтобы все введённые данные сохранились, и пользователь, закрыв браузер и через какое-то время вернувшись, мог не набирать их заново.
function saveToStorage(data) { try { window.localStorage.setItem('some-key', JSON.stringify(data)) } catch { alert('Failed to save data to local storage.') }}function loadFromStorage() { try { return JSON.parse(window.localStorage.getItem('some-key')) } catch { alert('Failed to load data from local storage.') }}// Код обработки формыfunction nextStep() { // При переходе сохраняем всё, что введено saveToStorage(formData)}
function saveToStorage(data) { try { window.localStorage.setItem('some-key', JSON.stringify(data)) } catch { alert('Failed to save data to local storage.') } } function loadFromStorage() { try { return JSON.parse(window.localStorage.getItem('some-key')) } catch { alert('Failed to load data from local storage.') } } // Код обработки формы function nextStep() { // При переходе сохраняем всё, что введено saveToStorage(formData) }
Разница между local
и session
в длительности хранения данных. Данные из session
сотрутся, когда пользователь закроет вкладку с приложением. Данные же из local
не стираются сами по себе.
На практике
Скопированосоветует Скопировано
Чтобы проверить, есть ли в navigator
необходимая вам фича, используйте in
:
if ('bluetooth' in navigator) { // Есть доступ к Bluetooth API}if ('serviceWorker' in navigator) { // Есть доступ к Service Worker API}
if ('bluetooth' in navigator) { // Есть доступ к Bluetooth API } if ('serviceWorker' in navigator) { // Есть доступ к Service Worker API }
screen
СкопированоЧтобы узнать, сколько пикселей занимает по ширине экран без полосы прокрутки (актуально для Windows, где полоса прокрутки отнимает какое-то пространство), используйте avail
:
// Без учёта полосыconst screenWidth = screen.width// С учётом полосы прокруткиconst withoutScrollBar = screen.availWidth
// Без учёта полосы const screenWidth = screen.width // С учётом полосы прокрутки const withoutScrollBar = screen.availWidth
location
СкопированоЧтобы программно перейти на другую страницу, используйте location
.
Перейти по адресу на текущем сайте:
location.href = '/another-page'
location.href = '/another-page'
Чтобы перейти на другой сайт, укажите его URL полностью:
location.href = 'https://google.com'
location.href = 'https://google.com'
Чтобы узнать полный путь от корня сайта, используйте location
:
// https://out-great-service.io/full/path/to/current/pageconst path = location.pathnameconsole.log(path)// '/full/path/to/current/page'
// https://out-great-service.io/full/path/to/current/page const path = location.pathname console.log(path) // '/full/path/to/current/page'
history
СкопированоЧтобы изменить адрес без перезагрузки страницы, используйте history
:
history.pushState(null, '', '/new/page/url')
history.pushState(null, '', '/new/page/url')
Для передачи данных, ассоциированных с переходом, используйте первый аргумент в history
:
const transitionData = { userName: 'Alex' }history.pushState(transitionData, '', '/new/page/url')
const transitionData = { userName: 'Alex' } history.pushState(transitionData, '', '/new/page/url')
После изменения url может потребоваться изменить заголовок - используйте document
.
document.title = 'Это новая страница!'
document.title = 'Это новая страница!'
localStorage
СкопированоИспользуйте функции-обёртки, чтобы получать доступ к хранилищу безопасно и не забывать превращать данные в JSON-строку при записи и в объект при чтении:
function saveToStorage(key, data) { try { // Если браузер не поддерживает localStorage, // блок try обезопасит код от неожиданной ошибки window.localStorage.setItem(key, JSON.stringify(data)) } catch { console.error('Failed to save data to local storage.') }}function loadFromStorage(key) { try { return JSON.parse(window.localStorage.getItem(key)) } catch { console.error('Failed to load data from local storage.') }}saveToStorage('user', {name: 'Alex', age: 26})loadFromStorage('user')
function saveToStorage(key, data) { try { // Если браузер не поддерживает localStorage, // блок try обезопасит код от неожиданной ошибки window.localStorage.setItem(key, JSON.stringify(data)) } catch { console.error('Failed to save data to local storage.') } } function loadFromStorage(key) { try { return JSON.parse(window.localStorage.getItem(key)) } catch { console.error('Failed to load data from local storage.') } } saveToStorage('user', {name: 'Alex', age: 26}) loadFromStorage('user')