在手持設(shè)備如此普遍的今天,位置信息對于應(yīng)用程序來講是極其重要的,打車應(yīng)用可以根據(jù)用戶的位置信息呼叫附近的車輛,團購軟件可以根據(jù)當(dāng)前的位置推薦附近的影院和美食,地圖應(yīng)用可以根據(jù)用戶的位置快速規(guī)劃到目的地的路線,可以說位置信息對于移動應(yīng)用是不可或缺的。
為了順應(yīng)這個潮流,HTML5為我們提供了Geolocation庫,有了它我們就能夠在Web應(yīng)用中輕而易舉地實現(xiàn)上述這些功能。那么今天我就為大家介紹一下這個庫的使用。
基本用法
首先,我們可以從瀏覽器的navigator對象中通過geolocation屬性獲取到一個Geolocation的實例,如下圖所示:
![](/d/20211016/92fda5322f4cce2a5f77c7835e8ce4c3.gif)
圖中我們可以看到,Geolocation類有三個常用的方法,他們分別是:
1.getCurrentPosition: 用于獲取當(dāng)前的位置信息
2.watchPosition: 用于在位置變化時實時監(jiān)測位置信息
3.clearWatch: 取消正在運行的監(jiān)測操作
我們先來看一下getCurrentPosition方法,下面是它的函數(shù)簽名:
JavaScript Code復(fù)制內(nèi)容到剪貼板
- navigator.geolocation.getCurrentPosition(success[, error[, options]]);
第一個參數(shù)用于指定一個成功后的處理函數(shù),第二參數(shù)用于指定一個錯誤處理函數(shù),第三個用于給函數(shù)提供一些可選的配置項?,F(xiàn)在我們就來調(diào)用這個函數(shù):
JavaScript Code復(fù)制內(nèi)容到剪貼板
- navigator.geolocation.getCurrentPosition(function(position) {
-
- console.log(position);
- }, function(error) {
-
- console.log(error);
- }, {
- enableHighAccuracy: true,
- timeout: 5000,
- maximumAge: 0
- });
一旦這段代碼運行起來,瀏覽器窗口就會彈出一個確認(rèn)框,請求用戶進行位置定位的授權(quán):
![](/d/20211016/35db343e8fa00b65387f9b57ffc55e88.gif)
如果我們點擊Allow允許該站點進行位置定位,該函數(shù)就開始從設(shè)備獲取位置信息,并觸發(fā)成功的回調(diào)函數(shù),并將位置信息對象傳入回調(diào)函數(shù)中,上面的代碼中我們在控制臺打印了position,控制臺信息如下:
![](/d/20211016/eabd174e258936769e707861add2cfaf.gif)
可以看到,position實際上是一個Geoposition對象的實例,其中包括coords和timestamp兩個屬性,后者是一個時間戳,記錄獲取到位置時的時間,coords里面包含了很多位置有關(guān)的信息:
accuracy: 位置的精確度范圍,單位為米
altitude: 海拔高度,單位為米,如果設(shè)備不支持高度感應(yīng),則該屬性為null
altitudeAccuracy: 海拔精確度范圍,單位為米,如果設(shè)備不支持高度感應(yīng),則該屬性為null
speed: 設(shè)備移動的速度,單位為米/秒,如果設(shè)備不能提供速度信息,該屬性為null
heading: 當(dāng)前移動的方向,以數(shù)字表示,單位為角度,以順時針[0, 360)度表示偏離正北方的角度,0表示正北方向,90度表示正東方向,180度表示正南方向,270表示正西方向;需要注意的是,如果speed為0,則heading會是NaN,如果設(shè)備不能提供方向信息,則該屬性為null
longitude: 經(jīng)度信息
latitude: 緯度信息
我們在成功的回調(diào)函數(shù)中接收到這些信息,可以根據(jù)實際的設(shè)備和應(yīng)用場景獲取相應(yīng)的信息,做進一步的操作。
回到剛才的確認(rèn)框,如果我們點擊了Block阻止該站點獲取當(dāng)前的位置信息,代碼就會授權(quán)失敗,相應(yīng)地,失敗的回調(diào)函數(shù)就會被觸發(fā),error錯誤對象也會被傳入回調(diào)函數(shù),我們的打印信息如下:
![](/d/20211016/ac2e8a5487498fc9402c90530c40a1ec.gif)
可以看到error參數(shù)是一個PositionError實例,包含一個錯誤碼code和message,分別表示錯誤的類型和錯誤提示消息,其中錯誤碼有以下幾種:
1: PERMISSION_DENIED - 用戶拒絕了授權(quán)請求,授權(quán)失敗
2: POSITION_UNAVAILABLE - 因為一些內(nèi)部錯誤,導(dǎo)致位置獲取失敗
3: TIMEOUT - 超時,超過了配置的超時時間后還未獲取到位置信息
上面就是失敗的回調(diào)函數(shù),一般獲取位置出現(xiàn)錯誤時,我們都要及時捕獲,并做相應(yīng)的處理操作,以獲取好的用戶體驗,這一點很重要。
在上面的調(diào)用中,我們還傳入了第三個參數(shù),一個簡單的對象,里面包含了幾個配置信息,它們都是用來配置函數(shù)運行參數(shù)的:
enableHighAccuracy: 默認(rèn)值為false,如果指定為true,則表示在設(shè)備支持的情況下,盡可能獲取高精準(zhǔn)度的數(shù)據(jù),但這會在時間和電量方面存在一定的消耗
timeout: 用于指定一個超時時間,單位為毫秒,表示在超時后停止位置獲取的操作,默認(rèn)值是Infinity,表示直到獲取到數(shù)據(jù)后才停止該操作的進行
maximumAge: 用于指定一個緩存位置信息的最長時間,在這個時間段內(nèi),獲取位置時會從緩存中取,單位為毫秒,默認(rèn)值為0,表示不使用緩存,每次都取新的數(shù)據(jù)
上面是關(guān)于getCurrentPosition方法的介紹,在某些場景下,例如路線導(dǎo)航應(yīng)用,我們需要實時地獲取最新位置,進而為用戶規(guī)劃最新的路線,這時,上面的方法已經(jīng)不能很好的滿足需求了,我們需要使用watchPosition方法:
JavaScript Code復(fù)制內(nèi)容到剪貼板
- watchId = navigator.geolocation.watchPosition(success[, error[, options]]);
watchPosition方法的使用方式和getCurrentPosition類似,不同的是,success函數(shù)會執(zhí)行多次,一旦獲取到最新的位置數(shù)據(jù),success函數(shù)就會被觸發(fā),與之相似地,如果連續(xù)獲取最新的數(shù)據(jù)失敗時,error函數(shù)也會被執(zhí)行多次。
大家或許會注意到,上面的函數(shù)簽名中,會返回一個watchId,它標(biāo)示著當(dāng)前的watch操作,當(dāng)我們位置跟蹤任務(wù)完成后,可以使用clearWatch函數(shù)將這個watchId清除即可:
JavaScript Code復(fù)制內(nèi)容到剪貼板
- navigator.geolocation.clearWatch(watchId);
上面就是Geolocation的常用的三個API,日常開發(fā)中我們可根據(jù)實際情況選用合適的方法,進而獲取用戶的位置信息。
現(xiàn)在大部分瀏覽器都已支持Geolocation了,可是為了兼容低版本的瀏覽器,我們需要判斷它的支持情況:
JavaScript Code復(fù)制內(nèi)容到剪貼板
- if ('geolocation' in navigator) {
-
- } else {
-
- }
最后,我們用一個簡單的例子來演示在開發(fā)中是如何使用Geolocation的:
JavaScript Code復(fù)制內(nèi)容到剪貼板
- var API = {
-
- getSurroundingRecommendations: function(longitude, latitude, callback) {
-
- setTimeout(function() {
- var data = [
- {
-
- },
- {
-
- }
- ];
- callback(data);
- }, 500);
- }
- };
-
- document.addEventListener('DOMContentLoaded', function() {
-
- if (!'geolocation' in navigator) {
- console.log('Geolocation is not supported in your browser');
- return;
- }
-
- var successHandler = function(position) {
- var coords = position.coords,
- longitude = coords.longitude,
- latitude = coords.latitude;
-
- API.getSurroundingRecommendations(longitude, latitude, function(data) {
- console.log(data);
- });
- },
- errorHandler = function(error) {
- console.log(error.code, error.message);
- },
- options = {
- enableHighAccuracy: true,
- timeout: 5000,
- maximumAge: 0
- };
-
- navigator.geolocation.getCurrentPosition(successHandler, errorHandler, options);
-
- }, false);
-
在上面的代碼中,首先我們定義一個根據(jù)當(dāng)前位置獲取推薦數(shù)據(jù)的方法,然后在文檔加載完成后,開始試圖獲取當(dāng)前位置,并調(diào)研這個方法,獲取模擬的數(shù)據(jù),真是開發(fā)環(huán)境中,可能會進一步利用返回的數(shù)據(jù)做渲染UI等操作。
網(wǎng)絡(luò)設(shè)備
位置服務(wù)用于估計您所在位置的本地網(wǎng)絡(luò)信息包括:有關(guān)可見 WiFi 接入點的信息(包括信號強度)、有關(guān)您本地路由器的信息、您計算機的 IP 地址。位置服務(wù)的準(zhǔn)確度和覆蓋范圍因位置不同而異。
總的來說,在PC的瀏覽器中 HTML5 的地理位置功能獲取的位置精度不夠高,如果借助這個 HTML5 特性做一個城市天氣預(yù)報是綽綽有余,但如果是做一個地圖應(yīng)用,那誤差還是太大了。不過,如果是移動設(shè)備上的 HTML5 應(yīng)用,可以通過設(shè)置 enableHighAcuracy 參數(shù)為 true,調(diào)用設(shè)備的 GPS 定位來獲取高精度的地理位置信息。
可選項
事實上,上述getCurrentPosition函數(shù)還支持第三個可選的參數(shù),是一個 Option Object,一共有三個選項可以設(shè)定:
JavaScript Code復(fù)制內(nèi)容到剪貼板
- var options = {
- enableHighAccuracy: false,
- timeout: 5000,
- maximumAge: 60000
- }
其中timeout是設(shè)定地理位置獲取的超時時間(單位為毫秒,用戶選擇允許的時間不計算在內(nèi));而maximumAge表示允許設(shè)備從緩存中讀取位置,緩存的過期時間,單位是毫秒,設(shè)為0來禁用緩存讀取。如果返回的是緩存中的時間,會在timestamp中反映出來。