最近公司项目需要优化表单的输入方式,其中有一项是让用户从地图中选择地理位置,而不是在输入框中填写。一番百度之后发现腾讯地图贴心的做了一个地图选点组件,调用方式也很简单,于是决定用这个组件。
调用方式
第一种方式是iframe内嵌地图组件的方式,这种方式通过postmessage来获取用户选择地址的相关信息,适用于在页面的一部分放置地图组件的情况;
另外一种方式就是直接打开一个新的地图选择页面,同时将用户选择后要返回的页面地址以查询参数的形式传递出去,从而可以使用户在选择地址之后,可以跳转回来。
由于我采用了第二种方式,下面就详细说说第二种方式的使用以及遇到的坑。
整体来说,第二种调用方式,基本是基于url的查询参数进行通信的,举个例子:
<a href="http://apis.map.qq.com/tools/locpicker?search=1&type=0&backurl=https://baidu.com&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77&referer=myapp">
<input placeholder="请选择地址" readonly>
</a>
上面的a标签所对应的(url)会跳转到腾讯的地图选点页面,同时提供了几个查询参数:
key是你在腾讯地图平台申请的key;backurl是用户点击后会返回的表单所在页面地址。其他的配置类参数见详见文档。
这里我填了baidu.com作为backurl,这意味着,当用户在地图中点击地址后,就会跳转到baidu.com。同时会有一个查询字符串跟在后面,里面包含了经纬度信息,通常是我们想要的,如下图。此外还包含了addr,city...等一系列有用信息。接下来就是在页面中监听unload事件,提取url中的信息,填到输入框。
一个可能的坑
假如你的backurl页面中也带有查询字符串,比如是baidu.com?foo=1&bar=2
,这时,调用腾讯地址选择组件的url就会变成这样:
http://apis.map.qq.com/tools/locpicker?search=1&type=0&backurl=https://baidu.com?foo=1&bar=2&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77&referer=myapp
最终页面会跳转到https://baidu.com?foo=1&latng=...
,你会发现bar=2
这个原来页面上的参数会丢失。如果这个参数对后台比较重要,那么页面将无法正确渲染。
解决办法是将&
转义为%26
,保证backurl的正确路径,其实也就是用到了encodeURIComponent
这个函数:
encodeURIComponent('&') // => %26
//不会丢失参数的URL
//http://apis.map.qq.com/tools/locpicker?search=1&type=0&backurl=https://baidu.com?foo=1%26bar=2&key=OB4BZ-D4W3U-B7VVO-4PJWW-6TKDJ-WPB77&referer=myapp
同样的情况还有可能出现在微信的服务号授权上,也是同样的道理。(完)