HTML5 - 地理位置
HTML5 - Geolocation API
Section titled “HTML5 - Geolocation API”HTML5 Geolocation API 提供了一种标准方法,允许 Web 应用程序在用户明确许可的情况下访问用户的地理位置。这使得位置感知功能成为可能,例如查找附近的兴趣点、提供导航、为内容添加地理标签,或根据区域定制内容。
该 API 利用设备和浏览器可用的各种数据源,如 GPS(最准确,通常在移动设备上)、Wi-Fi 网络定位、蜂窝基站三角测量或 IP 地址查找(最不准确)来工作。
隐私至关重要: 浏览器必须先获得用户的许可,才能与网站共享位置数据。用户可以拒绝许可,API 提供处理此类拒绝的机制。
访问 Geolocation 对象
Section titled “访问 Geolocation 对象”通过 navigator.geolocation 对象访问 Geolocation API。你应该首先检查此对象是否存在,以确保浏览器支持。
if ('geolocation' in navigator) { // Geolocation is supported console.log('Geolocation API available.'); // Proceed to use the API methods...} else { // Geolocation is not supported by this browser console.error('Geolocation API is not available in this browser.'); // Inform the user or disable location features}Geolocation 方法
Section titled “Geolocation 方法”navigator.geolocation 对象提供了三个主要方法:
| 方法 | 描述 |
|---|---|
getCurrentPosition(successCallback, [errorCallback], [options]) | 作为一次性请求检索设备的当前位置。成功时调用 successCallback 并传入一个 GeolocationPosition 对象;失败时调用 errorCallback 并传入一个 GeolocationPositionError 对象。 |
watchPosition(successCallback, [errorCallback], [options]) | 持续监测设备位置,并在位置显著变化时调用 successCallback。返回一个 ID 值,可用于停止监测。 |
clearWatch(watchId) | 使用由 watchPosition() 返回的 ID 停止由该调用启动的正在进行的定位监测过程。 |
GeolocationPosition 对象(成功回调)
Section titled “GeolocationPosition 对象(成功回调)”传递给 getCurrentPosition 或 watchPosition 的 successCallback 函数接收一个包含位置信息的 GeolocationPosition 对象:
| 属性 | 类型 | 描述 |
|---|---|---|
coords | 对象 (GeolocationCoordinates) | 包含地理坐标和精度信息。 |
coords.latitude | Number | 纬度,以十进制度表示。 |
coords.longitude | Number | 经度,以十进制度表示。 |
coords.accuracy | Number | 纬度和经度估计的精度,以米为单位。 |
coords.altitude | Number | null | [可选] 海拔高度,以 WGS 84 椭球体上方米为单位,如果不可用则为 null。 |
coords.altitudeAccuracy | Number | null | [可选] 海拔高度估计的精度,以米为单位,如果不可用则为 null。 |
coords.heading | Number | null | [可选] 行进方向,以度为单位(0=北,90=东等),如果不可用则为 null。 |
coords.speed | Number | null | [可选] 当前地面速度,以米/秒为单位,如果不可用则为 null。 |
timestamp | Number (DOMTimeStamp) | 检索位置信息的时间(自 epoch 以来的毫秒数)。 |
示例:获取当前位置
Section titled “示例:获取当前位置”function handleSuccess(position) { const latitude = position.coords.latitude; const longitude = position.coords.longitude; const accuracy = position.coords.accuracy; const timestamp = new Date(position.timestamp);
console.log(`Latitude: ${latitude}°`); console.log(`Longitude: ${longitude}°`); console.log(`Accuracy: ${accuracy} meters`); console.log(`Timestamp: ${timestamp.toLocaleString()}`);
// Update UI, show map, etc. document.getElementById('locationInfo').innerHTML = `Lat: ${latitude.toFixed(5)}, Long: ${longitude.toFixed(5)} (Accuracy: ${accuracy}m)`;}
function handleError(error) { let errorMessage = 'An unknown error occurred.'; switch (error.code) { case error.PERMISSION_DENIED: errorMessage = "User denied the request for Geolocation."; break; case error.POSITION_UNAVAILABLE: errorMessage = "Location information is unavailable."; break; case error.TIMEOUT: errorMessage = "The request to get user location timed out."; break; case error.UNKNOWN_ERROR: errorMessage = "An unknown error occurred."; break; } console.error(`Geolocation Error (${error.code}): ${errorMessage}`); document.getElementById('locationInfo').textContent = `Error: ${errorMessage}`;}
function getLocation() { if ('geolocation' in navigator) { document.getElementById('locationInfo').textContent = 'Requesting location...'; navigator.geolocation.getCurrentPosition(handleSuccess, handleError, { enableHighAccuracy: true, // Request more accurate position (might use more power) timeout: 10000, // Maximum time (ms) to wait for a position maximumAge: 0 // Don't use a cached position, get a fresh one }); } else { document.getElementById('locationInfo').textContent = 'Geolocation is not supported by your browser.'; }}GeolocationPositionError 对象(错误回调)
Section titled “GeolocationPositionError 对象(错误回调)”可选的 errorCallback 函数在定位检索失败时接收一个 GeolocationPositionError 对象:
| 属性 | 类型 | 描述 |
|---|---|---|
code | Number | 表示错误类型的数字代码(见下文)。 |
message | String | 对错误的易读描述。 |
可能的错误码 (error.code):
| 代码 | 常量 | 描述 |
|---|---|---|
| 1 | PERMISSION_DENIED | 用户拒绝授予权限。 |
| 2 | POSITION_UNAVAILABLE | 网络不可用或无法获得卫星定位。 |
| 3 | TIMEOUT | 在确定位置之前请求超时。 |
定位选项 (PositionOptions)
Section titled “定位选项 (PositionOptions)”getCurrentPosition 和 watchPosition 的可选第三个参数是一个 PositionOptions 对象:
| 属性 | 类型 | 默认值 | 描述 |
|---|---|---|---|
enableHighAccuracy | Boolean | false | 表示应用程序偏好尽可能准确的结果。这可能会消耗更多电量(例如,启用 GPS)并花费更长时间。设置为 false 可以让设备省电。 |
timeout | Number | Infinity | 设备允许返回位置的最长时间,以毫秒为单位。如果花费时间超过此值,则调用 errorCallback,错误码为 TIMEOUT。 |
maximumAge | Number | 0 | 指定应用程序愿意接受的缓存位置的最大时效(以毫秒为单位)。设置为 0 以强制检索新的位置。设置为 Infinity 以接受任何缓存位置,无论其时效如何。 |
完整示例页面
Section titled “完整示例页面”<!DOCTYPE html><html><head> <title>Geolocation Example</title> <style> body { font-family: sans-serif; } #locationInfo { margin-top: 10px; padding: 10px; border: 1px solid #ccc; background-color: #f9f9f9; } </style></head><body> <h1>HTML5 Geolocation</h1> <button onclick="getLocation()">Get My Location</button> <button onclick="watchLocation()">Watch My Location</button> <button onclick="stopWatching()">Stop Watching</button> <div id="locationInfo">Click 'Get My Location' or 'Watch My Location'.</div>
<script> let watchId = null;
function handleSuccess(position) { const latitude = position.coords.latitude; const longitude = position.coords.longitude; const accuracy = position.coords.accuracy; const timestamp = new Date(position.timestamp); console.log("Position Update:", position);
document.getElementById('locationInfo').innerHTML = `Lat: ${latitude.toFixed(5)}, Long: ${longitude.toFixed(5)}<br> Accuracy: ${accuracy} meters<br> Timestamp: ${timestamp.toLocaleString()}`; }
function handleError(error) { let errorMessage = 'An unknown error occurred.'; // ... (error handling switch statement as above) ... switch (error.code) { case error.PERMISSION_DENIED: errorMessage = "User denied the request for Geolocation."; break; case error.POSITION_UNAVAILABLE: errorMessage = "Location information is unavailable."; break; case error.TIMEOUT: errorMessage = "The request to get user location timed out."; break; case error.UNKNOWN_ERROR: errorMessage = "An unknown error occurred."; break; } console.error(`Geolocation Error (${error.code}): ${errorMessage}`); document.getElementById('locationInfo').textContent = `Error: ${errorMessage}`; }
const options = { enableHighAccuracy: true, timeout: 10000, maximumAge: 0 };
function getLocation() { if ('geolocation' in navigator) { document.getElementById('locationInfo').textContent = 'Requesting location...'; navigator.geolocation.getCurrentPosition(handleSuccess, handleError, options); } else { document.getElementById('locationInfo').textContent = 'Geolocation is not supported.'; } }
function watchLocation() { if ('geolocation' in navigator) { if (watchId) { console.log("Already watching location."); return; } document.getElementById('locationInfo').textContent = 'Watching location...'; // Start watching, store the returned ID watchId = navigator.geolocation.watchPosition(handleSuccess, handleError, options); console.log("Started watching location with ID:", watchId); } else { document.getElementById('locationInfo').textContent = 'Geolocation is not supported.'; } }
function stopWatching() { if (watchId !== null && 'geolocation' in navigator) { navigator.geolocation.clearWatch(watchId); console.log("Stopped watching location with ID:", watchId); document.getElementById('locationInfo').textContent = 'Stopped watching location.'; watchId = null; } else { console.log("Not currently watching location."); } } </script></body></html>