背景
到新公司的第二个项目,就是和小伙伴们一起做一个H5的商城,主要在微信内,但也要考虑到其他浏览器。其中,首页需要根据当前用户的经纬度找到距离最近的门店并展示。前端需要做的工作就是获取用户的经纬度然后查询后台接口并渲染页面。
目标与分析
我们的目标是经过封装之后,只需要调用一个方法就可以拿到返回的位置信息。
我们需要做的事情是,针对不同的端(微信H5和其他浏览器环境)封装不同的类,再通过一个方法通过 UA 区分,调用不同环境对应的类获取位置。
在微信内部,经过反复的实践之后,不论是通过原生的 HTML5 定位,还是通过第三方(如百度或腾讯地图) jsapi 获取位置,不仅定位时间长,甚至经常出现定位失败的情况,严重影响用户体验,尤其对于大部分信息流都依赖于用于位置的商城首页来说,是完全无法接受的。所以在微信内我们只有微信 sdk 这一种选择;
而对于浏览器端,通过第三方的地图 jsapi 或定位组件,可以稳定且较快速地获取位置信息,为了与微信内尽量保持一致,我们选择的是腾讯地图 jsapi。
解决方案
Talk is cheap, show me the code. 废话不多说,直接上代码:
1. 在浏览器中,通过腾讯地图jsapi获取位置
1.1 在项目的 html 模版文件中引入腾讯地图 jsapi
<!-- index.html -->
<script charset="utf-8" src="https://map.qq.com/api/js?v=2.exp&key=腾讯地图key&referer=应用名称"></script>
说明:
使用腾讯地图 jsapi, 需要先去腾讯地图开放平台申请自己的账号,然后创建自己的应用,将腾讯地图key 和创建的应用名称替换上面的值。
1.2 调用获取位置接口,获取位置信息
为了方便复用,我们单独封装一个腾讯地图 jsapi 的类,命名为 tMap.js
// tMap.js
const qq = window.qq
var geolocation = null
if (qq && qq.maps) {
// 初始化定位组件
geolocation = new qq.maps.Geolocation(
'QVLBZ-YUULR-OUMW7-WKXFD-4SUWS-UDBIA',
'mymap'
)
}class TMap {
// 获取定位计数器 用于定位失败时累计次数 超过3次后不再继续,抛出定位失败错误
getPositionCount = 0
// 对外暴露的获取位置接口
getLocation () {
return new Promise((resolve, reject) => {
// 定位成功回调
this.getTMapLocation(resolve, reject)
})
}
// 调用腾讯地图获取位置
getTMapLocation (success, fail) {
const _self = this
// 定位成功回调
const showPosition = position => {
uni.setStorage({









