Кратко
Скопировано позволяет запросить у пользователя данные о географическом местоположении.
Как пишется
СкопированоПолучить доступ к геолокации позволяет свойство navigator объекта navigator:
navigator.geolocation
navigator.geolocation
Как понять
СкопированоИногда может понадобиться узнать, где находится пользователь. Например, мы хотим показать на карте, где расположен ближайший к нему пункт выдачи товаров.
Для этого браузер предлагает своё API. Когда мы воспользуемся свойством navigator, в ответе получим интерфейс Geolocation, — он позволяет работать с данными геопозиции:
Geolocation {}
Geolocation {}
Внутри него:
clearWatch: ƒ clearWatch()getCurrentPosition: ƒ getCurrentPosition()watchPosition: ƒ watchPosition()constructor: ƒ Geolocation()Symbol(Symbol.toStringTag): "Geolocation"[[Prototype]]: Object
clearWatch: ƒ clearWatch()
getCurrentPosition: ƒ getCurrentPosition()
watchPosition: ƒ watchPosition()
constructor: ƒ Geolocation()
Symbol(Symbol.toStringTag): "Geolocation"
[[Prototype]]: Object
Для Geolocation есть различные методы: get, watch и clear. Если их вызвать, то пользователь получит уведомление. Например, в Chrome появится следующее диалоговое окно:

Если человек одобрит запрос, мы получим возможность работать с интерфейсом Geolocation:
GeolocationPosition { coords: GeolocationCoordinates, timestamp: 1665141114856}
GeolocationPosition {
coords: GeolocationCoordinates,
timestamp: 1665141114856
}
Он включает объект Geolocation с данными геолокации пользователя и параметр timestamp со временем получения координат:
GeolocationCoordinates { latitude: 36.01068878173828, longitude: 37.20875549316406, altitude: null, accuracy: 40, altitudeAccuracy: null, …}
GeolocationCoordinates {
latitude: 36.01068878173828,
longitude: 37.20875549316406,
altitude: null,
accuracy: 40,
altitudeAccuracy: null,
…
}
Чаще всего используются широта latitude и долгота longitude. Помимо них в объекте содержатся:
altitude— отвечает за высоту в метрах над эллипсоидом (что за эллипсоид под нами?);accuracy— точность широты и долготы в метрах (например, 40 метров);altitude— уровень точности высоты над эллипсоидом в метрах;Accuracy heading— направление движения. Угол, который отсчитывается по часовой стрелке относительно истинного севера и может принимать значения от 0° до 360°;speed— скорость движения в метрах в секунду.
Как узнать геолокацию единожды
СкопированоЧтобы получить координаты один раз, воспользуйтесь методом get и передайте внутрь колбэк. Его аргументом в случае успеха выступит объект Geolocation:
navigator.geolocation.getCurrentPosition(position => { const { latitude, longitude } = position.coords})// Записываем в переменные latitude и longitude// координаты пользователя
navigator.geolocation.getCurrentPosition(position => {
const { latitude, longitude } = position.coords
})
// Записываем в переменные latitude и longitude
// координаты пользователя
Кроме колбэка в get можно передать ещё два аргумента: функцию на случай ошибки и объект с дополнительными опциями:
navigator.geolocation.getCurrentPosition(success, error, options)function error() { alert('Где ты вообще...') // На случай ошибки}const options = { enableHighAccuracy: true, maximumAge: 1000, timeout: 3600}
navigator.geolocation.getCurrentPosition(success, error, options)
function error() {
alert('Где ты вообще...') // На случай ошибки
}
const options = {
enableHighAccuracy: true,
maximumAge: 1000,
timeout: 3600
}
Опции помогают настроить запрос детальнее:
enable— просит передавать геолокацию особенно точно, жертвуя энергией устройства и временем;High Accuracy maximum— устанавливает время, по истечении которого кэшированную геолокацию следует обновить;Age timeout— устанавливает временной интервал обновления геолокации.
Наблюдать в динамике
СкопированоЕсли get позволяет узнать геолокацию единожды, то для наблюдения за постоянно меняющимся местоположением лучше использовать метод watch:
navigator.geolocation.watchPosition(position => { const { latitude, longitude } = position.coords})// Постоянно перезаписываем в latitude и longitude// координаты пользователя
navigator.geolocation.watchPosition(position => {
const { latitude, longitude } = position.coords
})
// Постоянно перезаписываем в latitude и longitude
// координаты пользователя
Метод watch без конца вызывает колбэк, чтобы данные не застаивались.
Остановить наблюдение
СкопированоМетод watch возвращает id текущего наблюдения. Его можно использовать в методе clear, чтобы прекратить наблюдение:
const geoId = navigator.geolocation.watchPosition(position => { // Наблюдаем за геолокацией и храним в geoId идентификатор})function geoWatchStopper() { navigator.geolocation.clearWatch(geoId) // Останавливаем наблюдение}
const geoId = navigator.geolocation.watchPosition(position => {
// Наблюдаем за геолокацией и храним в geoId идентификатор
})
function geoWatchStopper() {
navigator.geolocation.clearWatch(geoId)
// Останавливаем наблюдение
}
Как обработать ошибки
СкопированоВ методы get и watch можно передать колбэк на случай ошибок. За них отвечает объект GeolocationPosition, его удобно обрабатывать через конструкцию switch:
function handleError(error) { // Эту функцию можно передать колбэком в случае ошибок const { code } = error switch (code) { case GeolocationPositionError.TIMEOUT: // Время получения геолокации истекло break case GeolocationPositionError.PERMISSION_DENIED: // Пользователь запретил отслеживание своей геопозиции break case GeolocationPositionError.POSITION_UNAVAILABLE: // Получить местоположение не удалось break }}
function handleError(error) {
// Эту функцию можно передать колбэком в случае ошибок
const { code } = error
switch (code) {
case GeolocationPositionError.TIMEOUT:
// Время получения геолокации истекло
break
case GeolocationPositionError.PERMISSION_DENIED:
// Пользователь запретил отслеживание своей геопозиции
break
case GeolocationPositionError.POSITION_UNAVAILABLE:
// Получить местоположение не удалось
break
}
}
На практике
Скопированосоветует
Скопировано🛠 С помощью можно получить координаты пользователя, а после найти по ним место на карте. Для этого создадим небольшую функцию, которая соберёт ссылку с долготой и широтой, а после вставим её в iframe c картой:
// На клик по кнопке ищем локациюbutton.addEventListener('click', findLocation)function findLocation() { if (!navigator.geolocation) { status.textContent = 'Ваш браузер не дружит с геолокацией...' } else { navigator.geolocation.getCurrentPosition(success, error) } // Если всё хорошо, собираем ссылку function success(position) { const { longitude, latitude } = position.coords map.src = `https://www.openstreetmap.org/export/embed.html?bbox=${longitude}%2C${latitude}&layer=mapnik` } // Если всё плохо, просто напишем об этом function error() { status.textContent = 'Не получается определить вашу геолокацию :(' }}
// На клик по кнопке ищем локацию
button.addEventListener('click', findLocation)
function findLocation() {
if (!navigator.geolocation) {
status.textContent = 'Ваш браузер не дружит с геолокацией...'
} else {
navigator.geolocation.getCurrentPosition(success, error)
}
// Если всё хорошо, собираем ссылку
function success(position) {
const { longitude, latitude } = position.coords
map.src = `https://www.openstreetmap.org/export/embed.html?bbox=${longitude}%2C${latitude}&layer=mapnik`
}
// Если всё плохо, просто напишем об этом
function error() {
status.textContent = 'Не получается определить вашу геолокацию :('
}
}
Если кликнуть по кнопке, карта приблизится к вашему местоположению:
🛠 Удобно проверить в самом начале, есть ли у нас возможность работать с геолокацией. Для этого в нашей функции find есть следующая конструкция:
if (!navigator.geolocation) { status.textContent = 'Ваш браузер не дружит с геолокацией...'} else { navigator.geolocation.getCurrentPosition(success, error)}
if (!navigator.geolocation) {
status.textContent = 'Ваш браузер не дружит с геолокацией...'
} else {
navigator.geolocation.getCurrentPosition(success, error)
}
navigator принимает значения типа boolean, так что если с геолокацией нельзя поработать, мы можем сразу сообщить об этом. Но если всё хорошо, то остаётся лишь запросить геолокацию и передать её колбэкам 🙂