构建 HTML5 应用程序

将 Geolocation 集成到 Web 应用程序中

Brandon Satrom

下载代码示例

如果您拥有一部智能手机,可能已经得到指示你在哪里到所需位置要转,或在一些陌生的市镇中查找附近的餐厅、 酒店或加油站使用的应用程序或内置功能。这项设施的技术术语是地理定位,同时还描述了设备,可以使用外部位置数据 (全球定位系统 [GPS],单元格塔三角和 Wi-fi 数据),找出你哪里都和提供这一信息的应用程序或服务请求此数据的能力。您所在的位置通常是使用数据如纬度和经度、 标题、 速度、 方向和类似表示的。有了这些信息,设备可以提供功能,如转由转向导航或附近发生在 2 上午开放 taco 卡车的位置

定位就是一些我们认为是理所当然,我们在移动设备上,但其使用快速蔓延本机的移动应用程序。越来越多的笔记本电脑和移动 Pc 现在装有 GPS 芯片和网络的爆炸,一个可行的平台,为移动应用程序开发已激起对在浏览器中,右地理定位服务的需求。

幸运的是对我们来说,W3C 早拿上这一趋势,以及创建规范,描述了一种标准的方式使用 Web 应用程序中的从全球定位服务。规范,可以在 bit.ly/3r737c,并不是"正式"的 HTML5 的一部分,但因为我正在本系列中使用这个词来描述一组打开 Web 技术 — — W3C 一样 — — 不能错过的机会给你简要参观这令人兴奋的技术。

这个月的文章会给你的地理定位 API 概述和显示您如何你可以开始使用它,以及如何处理地理定位请求期间发生的错误的最常见类型。我讨论地理定位如何执行的台式机和移动浏览器,并总结与简单介绍一下如何使用 polyfilling 图书馆与较旧的浏览器,为用户提供基本地理定位的支持。

入门定位

W3C 规范,定位就是一个"… …提供与宿主设备相关的地理位置信息的脚本的访问的 API。"因为定位就是一个内置的 API,你要开始是支持它的浏览器。这次写作、 互联网资源管理器 9 (包括互联网资源管理器 9 Windows Phone 7.5,代号为"芒果"上),以及当前版本的 Chrome、 火狐、 Safari 和 Opera,所有支持地理定位,所以该规范是不仅得到广泛支持,但可能可用以相当大的一部分,您的用户群。

地理定位 API 住在全球的"导航器"对象在 JavaScript (窗口。navigator.geolocation)。它提供了两种方法可以使用定位服务: 一次性位置请求,并重复的位置更新。对于一次性请求,使用 getCurrentPosition 方法,如下所示:

navigator.geolocation.getCurrentPosition(function(position) {
       var coordinates = position.coords;
       console.log("Your latitude: " + coordinates.latitude + " and longitude:
         " + coordinates.longitude + " (Accuracy of:
         " + coordinates.accuracy + " meters)");
}, errorHandler, { maximumAge: 100, timeout: 6000, enableHighAccuracy: true});

方法 getCurrentPosition 接受三个参数。第一个是一个回调函数,将触发时浏览器成功确定当前设备的位置。第二是火灾发生错误的回调函数 (详细介绍,一会儿)。第三是对象文本用于指定地理定位选项。列出可用的选项和它们的默认值图 1

图 1 地理定位选项

可选择进行的操作 Description 数值
maximumAge 缓存的报告的位置 (以毫秒为单位) 的时间长度。 0 (默认值),则无限
超时 长时间 (以毫秒为单位),等待位置服务响应。 0 到无穷大 (默认值)
enableHighAccuracy 是否应该尝试使用高精度定位服务 (例如,GPS),在浏览器支持的浏览器和设备。 为 true,false (默认值)

成功处理程序提供了一个位置的对象包含有关当前用户的位置的重要属性。地理定位规范定义了几个属性,但只有三都一致地执行不同的浏览器: 经度、 纬度和准确性。其他属性如标题、 方向和高度可用于浏览器来执行,并在将来可能是非常有用的移动浏览方案。

对于重复的位置请求,地理定位对象提供了两个公共方法、 watchPosition 和 clearWatch ; watchPosition 可以使用像这样:

var watchId = navigator.geolocation.watchPosition(function(position) {
       var coordinates = position.coords;
       console.log("Your latitude: " + coordinates.latitude + " and longitude:
         " + coordinates.longitude + " (Accuracy of:
         " + coordinates.accuracy + " meters)");
}, errorHandler, {maximumAge: 100, timeout: 6000, enableHighAccuracy: true});

WatchPostion 方法相同的参数为 getCurrentPosition,成功处理程序、 错误处理程序和选项。 关键的区别是,watchPosition 立即返回 ID,用于标识功能问题。 WatchPosition 是一个重复的函数,因为浏览器将调用它每次它检测到更改的用户的位置,直到关闭窗口或脚本显式取消手表。 若要取消 watchPosition,您只需 watchPosition,所返回的 ID 与调用 clearWatch,如下所示:

clearWatch(watchId);

让我们看一个示例应用程序中使用 getCurrentPosition。 对于此示例,将继续使用 WebMatrix (http://aka.ms/webm) 面包我在我的上一篇文章中使用的示例。 该网站是一个用户可以订购烘烤和有其发送,但我想延长这一功能允许用户指定一个附近的砖和砂浆位置,他们会在哪里取顺序的地方。 百思买做店内的电子取货,我想做为繁华烘焙业。

我开始用我穿上了 HTML5 形式特色我 11 月文章修改的面包房示例应用程序 (msdn.microsoft.com/magazine/hh547102),然后添加一项功能,允许用户通过单击窗体上的链接选择附近的面包店取货。 我使用 Bing 地图 AJAX 控件 (你可以下载它在 msdn.microsoft.com/library/gg427610),和代表回升和航运节窗体的页添加适当的引用,并创建 HTML 元素包含我的地图后, 添加几个 div。 每个 div 包含链接,使用户可以在这两个选项之间进行切换。 当单击"兴趣捡您的订单,在我们的商店之一?"链接时,一个称为 locateBakery.js 的 JavaScript 文件执行的功能。 该函数的主要方法显示在图 2

图 2 locateBakery.js

var mapDiv = document.getElementById("map");
var _map = new Microsoft.Maps.Map(mapDiv, { credentials: myCredentials });
function hideMap() {
    $('#pickup').hide();
    $('#map').hide();
    $('#ship').show();
}
function displayError(msg) {
    $('#error').val(msg);
}
function placeLocationOnMap(latitude, longitude) {
    var location = new Microsoft.Maps.Location(latitude, longitude);
    var bakeries = lookupNearbyBakeries(latitude, longitude);
    _map.setView({ zoom: 12, center: location });
    // Add a pushpin to the map representing the current location
    var pin = new Microsoft.Maps.Pushpin(location);
    _map.entities.push(pin);
    for (var i=0;i<bakeries.length;i++) {
        _map.entities.push(bakeries[i]);
    }
}
function errorHandler(e) {
    if (e === 1) { // PERMISSION_DENIED
        hideMap();
    } else if (e === 2) { //POSITION_UNAVAILABLE
        displayError('Cannot find your location.
Make sure your network
        connection is active and click the link to try again.');
        hideMap();
    } else if (e === 3) { //TIMEOUT
        displayError('Cannot find your location.
Click the link to try again.');
        hideMap();
    }
}
function locate() {
    navigator.geolocation.getCurrentPosition(function (position) {
        var coordinates = position.coords;
        placeLocationOnMap(coordinates.latitude, coordinates.longitude);
    }, errorHandler);
}

查找函数调用 navigator.geolocation.getCurrentPosition 和提供的坐标的地方如果该调用成功,­LocationOnMap 函数,它可以放上一张地图,连同附近的面包店 (烘焙查找逻辑被省略的空间) 的列表的用户的位置。 这允许用户查找附近的面包店从中拿起她的命令。 结果所示图 3

Using Geolocation with the Bakery Application
图 3 使用地理定位与面包中应用

当然,定位就是依赖于网络的服务,所以你做什么地理定位失败时? 也许你也注意到 getCurrentPosition 和 watchPosition 函数指定称为 errorHandler 的第二个参数。 地理定位规范,对 getCurrentPosition 和 watchPosition 的调用应调用成功处理程序和错误处理程序。 当调用地理定位服务,有三个可能的错误:

  • 用户可以拒绝跟踪位置信息的浏览器的请求
  • 位置请求可能超时
  • 超时时间到期之前,可能会失败的位置请求

时将地理支持添加到您的应用程序中,您应务必处理所有三例。 在源中可以找到这样一个示例图 2,凡我显示一条错误消息和地理定位调用任何原因失败时,重新显示航运信息部分。

地理定位是如何工作的

尽管地理定位规范是相当规范中定义的每个浏览器必须向开发人员提供的公共 API,它没有什么可说关于准确定位应如何落实在浏览器中。 在一般的指导是每个浏览器应设法平衡精度的电力消耗的考虑,提供具有相当准确的坐标集的应用程序的目标。

台式机或笔记本电脑的情况下,大多数浏览器都使用相同的机制,提供地理数据,尽管不同取决于他们的后台服务。 在互联网浏览器 9 的情况下,到后来浏览器将收集您的 IP 地址或附近的 Wi-fi 热点的列表,然后将该信息传递给微软位置服务 (相同服务的内置位置设施 Windows Phone 设备使用) 为一组的坐标。 谷歌浏览器和 Mozilla 的火狐浏览器均还使用 IP 和 Wi-fi 热点数据,但依靠 Google 位置服务的实际的请求。 查找用户的位置定位服务方法牺牲一些准确性的速度 (和低功耗),和作为备份,或设备缺乏一个内置的 GPS 芯片时非常有用。

对于移动浏览器,情况是有点复杂,和同样是到浏览器的问题。 因为大多数现代智能手机 GPS 芯片,浏览器可以自由地使用在尝试移动操作系统所提供的 GPS 定位服务来获取更准确的坐标。 Windows Phone 7.5 上互联网浏览器 9、 Safari 对 iOS 的情况下,正是这些浏览器做些什么。 结果是,额外的电力消耗,通常是可接受的权衡,大多数移动的定位方案例如,转由转向导航中牺牲的更准确的位置。 很重要,但是请注意,只需使用 gps 全球定位保证移动设备的浏览器并不是因为芯片可用。 规范的叶子到浏览器上执行,因为浏览器或移动的底层 OS 服务可以选择回退到单元格塔三角或 IP 查找,或使用单元格三角剖分与 GPS 相结合。 (许多移动操作系统已经这么做本机应用程序,如其内置的位置服务的一部分)

对于 Web 应用程序开发人员,这是好消息,因为这意味着与地理定位,您可以构建跨平台的移动应用程序可以依赖位置设施本机设备,就像本机应用程序开发人员。

检测和 Polyfilling 地理支持

当将地理支持添加到您的应用程序,您需要考虑你的方法将为这些用户访问您的网站使用不受支持的浏览器。 我已经过讨论一系列,您确定在给定的浏览器是否支持地理定位的方法是通过执行手动功能检测 ("如果 (!! navigator.geolocation)") 或使用像 Modernizr 的库 (modernizr.com)。 For users without geolocation support, there are two courses of action: gracefully degrade the application or polyfill support via an external library. 第一个选项,您可以降低了您的应用程序,显示一个表单,让你给它们的位置,然后使用 (通过服务呼叫) 以确定的纬度和经度的该用户的用户。 我涵盖这种情况下,在这一系列,我 9 月的文章,所以我就不重复了。 这种情况下,并在在线代码示例,您可以查看 (msdn.microsoft.com/magazine/hh394148)。

我将涵盖这次有点更深入的第二个选项。 正如我在前面的文章中,提到过当你发现自己在市场的跨浏览器 polyfill HTML5 技术时,第一个去的地方是的 GitHub,他们已经在其中发布非常全面的列表的可用 polyfills Modernizr 的家 (bit.ly/eBMoLW)。 在撰写本文时,有三个地理定位 polyfills 列出。 我选择使用提供的保罗 · 爱尔兰 (bit.ly/q20TOl) 纯粹为例,这篇文章。

你可以从我 9 月的文章回顾 polyfill 是一个库,它提供了基于脚本的执行情况,对于 HTML5 的功能,并经常坚持记录的 API,该过程中的规范。 后一点很关键,因为这意味着我这样一个库添加到我的应用程序,一旦可以继续进行交互的功能,该功能的好像它完全支持在浏览器中,和我不必叉流我的程序和条件逻辑来支持较旧的浏览器。

像我刚做之前,本系列中,我用 Modernizr 帮我检测地理定位功能的支持,如果没有这种支持的存在,异步加载的 geolocationShim.js 脚本文件:

Modernizr.load({
  test: Modernizr.geolocation,
  nope: '../js/geolocationShim.js',
  complete: function() {
  locate();
  }
});

如果支持地理定位,则执行将继续查找功能。 如果不是,地理定位 polyfill 将加载并执行完成后,然后将继续查找功能。 当我运行该示例在互联网浏览器 9 这个逻辑时,一切正常工作,调用本机地理定位功能。

要测试什么这看起来像在较旧的浏览器中,我可以开放的互联网浏览器 9 F12 开发工具,并将浏览器模式切换为互联网浏览器 8。 当我这样做,并再次执行该页面时,Modernizr 将检测,地理定位不支持和加载我垫片。 然后,我 shim 的 getCurrentPosition 方法调用时,代码图 4 ,将会执行。

图 4 方法实现通过 Shim 的 getCurrentPosition

geolocation.getCurrentPosition = function(callback){   
  if (cache) callback(cache);
  $.getScript('//www.google.com/jsapi',function(){     
    cache = {
      coords : {
        "latitude": google.loader.ClientLocation.latitude,
        "longitude": google.loader.ClientLocation.longitude
      }
    };
    callback(cache);
  });   
};

因为此 polyfilling 库坚守地理定位 API 规范,并提供 getCurrentPosition 和手表­位置的方法,我不需要我主要的 getLocation 函数中执行的任何额外的检查或条件逻辑。

无论您选择优雅会降低您的应用程序,允许用户手动提供它们的位置,或尝试执行 shim,它在采用地理定位在您的应用程序,同时确保您的网站继续提供更完美的体验,但不要使用现代浏览器的人有选项。

很多世界所叫的 HTML5 或打开的 Web 技术,是一套面向实际的应用程序开发使得在 Web 上的技术。 Web 和桌面之间的差距正在缩小,并定位就是很好的例子是今天可能与 Web 应用程序。 在本文中,我介绍地理定位规范的基本知识。 我展示了如何你可以开始,地理定位实施跨桌面和移动浏览器,以及如何在较旧的浏览器支持 polyfill 地理定位。 现在是时候要将这个令人兴奋的功能添加到您的 Web 应用程序,所以,去今天做出一些令人敬畏的应用程序 !

如果您正在寻找在互联网浏览器 9 地理支持的详细信息,签出互联网浏览器 9 指南对于开发人员来说,在 msdn.microsoft.com/ie/ff468705。 地理定位为其他跨浏览器 polyfills,为签出的完整列表,在 bit.ly/qNE92g

最后,所有的这篇文章的演示 — — 可在线 — — 建成使用 WebMatrix,从微软免费的轻量级的 Web 开发工具。 您可以为自己在尝试 WebMatrix aka.ms/webm

Brandon Satrom 工程作为开发人员宣传员微软以外的奥斯汀。在他的博客 userinexperience.com ,可以发现在 Twitter 上 twitter.com/BrandonSatrom

衷心感谢以下 Microsoft 技术专家对本文的审阅: Jon Box, John Hrvatin, Clark SellAndy Zeigler