Кратко
Скопировано
позволяет запросить у пользователя данные о географическом местоположении.
Как пишется
СкопированоПолучить доступ к геолокации позволяет свойство 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
, так что если с геолокацией нельзя поработать, мы можем сразу сообщить об этом. Но если всё хорошо, то остаётся лишь запросить геолокацию и передать её колбэкам 🙂