使用地理位置 API

安全上下文:此功能仅在安全上下文(HTTPS)中可用,在某些或所有支持的浏览器中可用。

地理位置 API 用于检索用户的地理位置,以便例如可以使用地图 API 显示其位置。本文介绍了如何使用它的基本知识。

地理位置对象

可以通过Geolocation APInavigator.geolocation对象访问。

如果对象存在,则地理位置服务可用。您可以如下测试地理位置是否存在

js
if ("geolocation" in navigator) {
  /* geolocation is available */
} else {
  /* geolocation IS NOT available */
}

获取当前位置

要获取用户的当前位置,您可以调用getCurrentPosition()方法。这会启动一个异步请求来检测用户的位置,并查询定位硬件以获取最新的信息。确定位置后,将执行定义的回调函数。您可以选择提供第二个回调函数,以便在发生错误时执行。第三个可选参数是一个选项对象,您可以在其中设置返回位置的最大年龄、请求等待时间以及是否需要位置的高精度。

注意:默认情况下,getCurrentPosition()尝试以尽可能快的速度返回低精度结果。如果您需要快速回答而不管精度如何,这将很有用。例如,带有 GPS 的设备可能需要一分钟或更长时间才能获得 GPS 定位,因此可能会将不太精确的数据(IP 位置或 Wi-Fi)返回到getCurrentPosition()

js
navigator.geolocation.getCurrentPosition((position) => {
  doSomething(position.coords.latitude, position.coords.longitude);
});

以上示例将导致在获取位置时执行doSomething()函数。

监视当前位置

如果位置数据发生变化(无论是通过设备移动还是更精确的地理信息到达),您可以设置一个回调函数,该函数将使用更新的位置信息调用。这是使用watchPosition()函数完成的,该函数与getCurrentPosition()具有相同的输入参数。回调函数被多次调用,允许浏览器在您移动时更新您的位置,或者在使用不同的技术对您进行地理定位时提供更精确的位置。错误回调函数(与getCurrentPosition()一样是可选的)可以重复调用。

注意:您可以使用watchPosition()而无需初始getCurrentPosition()调用。

js
const watchID = navigator.geolocation.watchPosition((position) => {
  doSomething(position.coords.latitude, position.coords.longitude);
});

watchPosition()方法返回一个 ID 号码,可用于唯一标识请求的位置监视器;您将此值与clearWatch()方法一起使用以停止监视用户的位置。

js
navigator.geolocation.clearWatch(watchID);

微调响应

getCurrentPosition()watchPosition()都接受成功回调、可选的错误回调和可选的选项对象。

此对象允许您指定是否启用高精度、返回位置值的最高年龄(在此年龄之前,如果再次请求相同的位置,它将被缓存并重复使用;之后,浏览器将请求新的位置数据)以及超时值,该值决定了浏览器在超时之前尝试获取位置数据的时间。

watchPosition的调用可能如下所示

js
function success(position) {
  doSomething(position.coords.latitude, position.coords.longitude);
}

function error() {
  alert("Sorry, no position available.");
}

const options = {
  enableHighAccuracy: true,
  maximumAge: 30000,
  timeout: 27000,
};

const watchID = navigator.geolocation.watchPosition(success, error, options);

描述位置

用户的位置使用GeolocationPosition对象实例进行描述,该实例本身包含GeolocationCoordinates对象实例。

GeolocationPosition实例仅包含两件事,一个包含GeolocationCoordinates实例的coords属性,以及一个包含时间戳的timestamp属性,该时间戳以毫秒为单位给出Unix 时间,表示检索位置数据的时间。

GeolocationCoordinates实例包含许多属性,但您最常使用的两个是latitudelongitude,这是您在 map 上绘制位置所需的信息。因此,许多 Geolocation 成功回调看起来相当简单

js
function success(position) {
  const latitude = position.coords.latitude;
  const longitude = position.coords.longitude;

  // Do something with your latitude and longitude
}

但是,您可以从GeolocationCoordinates对象中获取许多其他信息,包括高度、速度、设备所面向的方向以及高度、经度和纬度数据的精度度量。

处理错误

如果在调用getCurrentPosition()watchPosition()时提供错误回调函数,则该函数期望其第一个参数为GeolocationPositionError对象实例。此对象类型包含两个属性,一个指示已返回哪种类型的错误的code,以及一个描述错误代码含义的人类可读message

您可以像这样使用它

js
function errorCallback(error) {
  alert(`ERROR(${error.code}): ${error.message}`);
}

示例

在以下示例中,地理位置 API 用于检索用户的纬度和经度。如果成功,则可用超链接将填充一个openstreetmap.org URL,该 URL 将显示其位置。

HTML

html
<button id="find-me">Show my location</button><br />
<p id="status"></p>
<a id="map-link" target="_blank"></a>

JavaScript

js
function geoFindMe() {
  const status = document.querySelector("#status");
  const mapLink = document.querySelector("#map-link");

  mapLink.href = "";
  mapLink.textContent = "";

  function success(position) {
    const latitude = position.coords.latitude;
    const longitude = position.coords.longitude;

    status.textContent = "";
    mapLink.href = `https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`;
    mapLink.textContent = `Latitude: ${latitude} °, Longitude: ${longitude} °`;
  }

  function error() {
    status.textContent = "Unable to retrieve your location";
  }

  if (!navigator.geolocation) {
    status.textContent = "Geolocation is not supported by your browser";
  } else {
    status.textContent = "Locating…";
    navigator.geolocation.getCurrentPosition(success, error);
  }
}

document.querySelector("#find-me").addEventListener("click", geoFindMe);

结果