使用 Geolocation API

Geolocation API 用於獲取使用者的當前位置,以便例如可以使用地圖 API 來顯示他們的位置。本文件解釋瞭如何使用它的基礎知識。

Geolocation 物件

可以透過 navigator.geolocation 物件訪問 Geolocation API

如果該物件存在,則表示地理定位服務可用。您可以透過以下方式測試地理定位是否存在:

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

獲取當前位置

要獲取使用者的當前位置,可以呼叫 getCurrentPosition() 方法。這會啟動一個非同步請求來檢測使用者的位置,並查詢定位硬體以獲取最新資訊。當位置確定後,將執行定義的 callback 函式。您可以選擇提供第二個 callback 函式,以在發生錯誤時執行。第三個可選引數是一個 options 物件,您可以在其中設定返回位置的最大年齡、請求等待時間以及是否需要高精度位置。

注意:預設情況下,getCurrentPosition() 嘗試以低精度結果儘快響應。如果您需要快速響應而不關心精度,這非常有用。例如,帶有 GPS 的裝置可能需要一分鐘或更長時間才能獲得 GPS 訊號,因此 getCurrentPosition() 可能會返回不太精確的資料(IP 地址定位或 Wi-Fi)。

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

上面的示例將在獲取到位置資訊後執行 doSomething() 函式。

監視當前位置

如果位置資料發生變化(由於裝置移動或收到更精確的地理資訊),您可以設定一個 callback 函式,該函式會在收到更新的位置資訊時被呼叫。這可以透過 watchPosition() 函式來實現,該函式具有與 getCurrentPosition() 相同的輸入引數。callback 函式會多次呼叫,允許瀏覽器在您移動時更新您的位置,或者在使用不同技術進行地理定位時提供更精確的位置。錯誤 callback 函式(與 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() 都接受一個成功 callback、一個可選的錯誤 callback 和一個可選的 options 物件。

此物件允許您指定是否啟用高精度、返回位置值的最大年齡(在此年齡之前將被快取並重用,如果再次請求相同位置;之後瀏覽器將請求新的位置資料)以及一個超時值,該值決定了在超時之前瀏覽器應該嘗試獲取位置資料多長時間。

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 例項僅包含兩項:一個 coords 屬性,其中包含 GeolocationCoordinates 例項;以及一個 timestamp 屬性,其中包含獲取位置資料時的時間戳,以毫秒為單位的 Unix 時間

GeolocationCoordinates 例項包含許多屬性,但您最常用的兩個是 latitudelongitude,它們是您在地圖上繪製位置所需的。因此,許多 Geolocation 成功 callback 函式看起來非常簡單:

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

  // Do something with your latitude and longitude
}

但是,您還可以從 GeolocationCoordinates 物件中獲取許多其他資訊,包括海拔、速度、裝置朝向以及海拔、經度和緯度資料的精度。

處理錯誤

如果呼叫 getCurrentPosition()watchPosition() 時提供了錯誤 callback 函式,它將接受一個 GeolocationPositionError 物件例項作為其第一個引數。此物件型別包含兩個屬性:一個 code,指示返回的錯誤型別;以及一個人類可讀的 message,描述了錯誤程式碼的含義。

您可以這樣使用它:

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

示例

在下面的示例中,Geolocation 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);

結果