HTML5新特性之Geolocation

时间:2022-11-17 16:21:54

在手持设备如此普遍的今天,位置信息对于应用程序来讲是极其重要的,打车应用可以根据用户的位置信息呼叫附近的车辆,团购软件可以根据当前的位置推荐附近的影院和美食,地图应用可以根据用户的位置快速规划到目的地的路线,可以说位置信息对于移动应用是不可或缺的。
为了顺应这个潮流,HTML5为我们提供了Geolocation库,有了它我们就能够在Web应用中轻而易举地实现上述这些功能。那么今天我就为大家介绍一下这个库的使用。
首先,我们可以从浏览器的navigator对象中通过geolocation属性获取到一个Geolocation的实例,如下图所示:
HTML5新特性之Geolocation
图中我们可以看到,Geolocation类有三个常用的方法,他们分别是:

getCurrentPosition: 用于获取当前的位置信息
watchPosition: 用于在位置变化时实时监测位置信息
clearWatch: 取消正在运行的监测操作

我们先来看一下getCurrentPosition方法,下面是它的函数签名:

navigator.geolocation.getCurrentPosition(success[, error[, options]]);

第一个参数用于指定一个成功后的处理函数,第二参数用于指定一个错误处理函数,第三个用于给函数提供一些可选的配置项。现在我们就来调用这个函数:

navigator.geolocation.getCurrentPosition(function(position) {
    //success handler code goes here
    console.log(position);
}, function(error) {
    //error handler code goes here
    console.log(error);
}, {//options
    enableHighAccuracy: true,
    timeout: 5000,
    maximumAge: 0
});

一旦这段代码运行起来,浏览器窗口就会弹出一个确认框,请求用户进行位置定位的授权:
HTML5新特性之Geolocation
如果我们点击Allow允许该站点进行位置定位,该函数就开始从设备获取位置信息,并触发成功的回调函数,并将位置信息对象传入回调函数中,上面的代码中我们在控制台打印了position,控制台信息如下:
HTML5新特性之Geolocation
可以看到,position实际上是一个Geoposition对象的实例,其中包括coordstimestamp两个属性,后者是一个时间戳,记录获取到位置时的时间,coords里面包含了很多位置有关的信息:

accuracy: 位置的精确度范围,单位为
altitude: 海拔高度,单位为,如果设备不支持高度感应,则该属性为null
altitudeAccuracy: 海拔精确度范围,单位为,如果设备不支持高度感应,则该属性为null
speed: 设备移动的速度,单位为米/秒,如果设备不能提供速度信息,该属性为null
heading: 当前移动的方向,以数字表示,单位为角度,以顺时针[0, 360)度表示偏离正北方的角度,0表示正北方向,90度表示正东方向,180度表示正南方向,270表示正西方向;需要注意的是,如果speed0,则heading会是NaN,如果设备不能提供方向信息,则该属性为null
longitude: 经度信息
latitude: 纬度信息

我们在成功的回调函数中接收到这些信息,可以根据实际的设备和应用场景获取相应的信息,做进一步的操作。
回到刚才的确认框,如果我们点击了Block阻止该站点获取当前的位置信息,代码就会授权失败,相应地,失败的回调函数就会被触发,error错误对象也会被传入回调函数,我们的打印信息如下:
HTML5新特性之Geolocation
可以看到error参数是一个PositionError实例,包含一个错误码codemessage,分别表示错误的类型和错误提示消息,其中错误码有以下几种:

1: PERMISSION_DENIED - 用户拒绝了授权请求,授权失败
2: POSITION_UNAVAILABLE - 因为一些内部错误,导致位置获取失败
3: TIMEOUT - 超时,超过了配置的超时时间后还未获取到位置信息

上面就是失败的回调函数,一般获取位置出现错误时,我们都要及时捕获,并做相应的处理操作,以获取好的用户体验,这一点很重要。
在上面的调用中,我们还传入了第三个参数,一个简单的对象,里面包含了几个配置信息,它们都是用来配置函数运行参数的:

enableHighAccuracy: 默认值为false,如果指定为true,则表示在设备支持的情况下,尽可能获取高精准度的数据,但这会在时间和电量方面存在一定的消耗
timeout: 用于指定一个超时时间,单位为毫秒,表示在超时后停止位置获取的操作,默认值是Infinity,表示直到获取到数据后才停止该操作的进行
maximumAge: 用于指定一个缓存位置信息的最长时间,在这个时间段内,获取位置时会从缓存中取,单位为毫秒,默认值为0,表示不使用缓存,每次都取新的数据

上面是关于getCurrentPosition方法的介绍,在某些场景下,例如路线导航应用,我们需要实时地获取最新位置,进而为用户规划最新的路线,这时,上面的方法已经不能很好的满足需求了,我们需要使用watchPosition方法:

watchId = navigator.geolocation.watchPosition(success[, error[, options]]);

watchPosition方法的使用方式和getCurrentPosition类似,不同的是,success函数会执行多次,一旦获取到最新的位置数据,success函数就会被触发,与之相似地,如果连续获取最新的数据失败时,error函数也会被执行多次。
大家或许会注意到,上面的函数签名中,会返回一个watchId,它标示着当前的watch操作,当我们位置跟踪任务完成后,可以使用clearWatch函数将这个watchId清除即可:

navigator.geolocation.clearWatch(watchId);

上面就是Geolocation的常用的三个API,日常开发中我们可根据实际情况选用合适的方法,进而获取用户的位置信息。
现在大部分浏览器都已支持Geolocation了,可是为了兼容低版本的浏览器,我们需要判断它的支持情况:

if ('geolocation' in navigator) {
  // getting usr's position
} else {
  // tips: your position is not available
}

最后,我们用一个简单的例子来演示在开发中是如何使用Geolocation的:

var API = {
    //get recommended data by current longitude and latitude
    getSurroundingRecommendations: function(longitude, latitude, callback) {
        //simulate data obtaining from server.
        setTimeout(function() {
            var data = [
                {
                    //item
                },
                {
                    //item
                }
            ];
            callback(data);
        }, 500);
    }
};

document.addEventListener('DOMContentLoaded', function() {
    //detect if Geolocation is supported
    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);

在上面的代码中,首先我们定义一个根据当前位置获取推荐数据的方法,然后在文档加载完成后,开始试图获取当前位置,并调研这个方法,获取模拟的数据,真是开发环境中,可能会进一步利用返回的数据做渲染UI等操作。
关于Geolocation的介绍就先到这里了,谢谢。