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