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