介绍
用户的地址选择往往是网络应用中不可缺少的一部分,可是遇到了以下问题:
- 地址数据难以收集
- 用户选择烦琐,需要手动查找冗长的下拉菜单
- 难以维护地理数据以及重用组件
LocationSelect插件具有以下特点,有效的解决了以上三个问题:
- 基于广泛使用的jQuery插件库,轻易实现组件重用。你也可以选择使用不使用任何脚本库的版本。
- 地理数据整理来自国家公布数据
- 自动判断用户地理位置并进行最大努力的自动选择
- 独立的json数据源,可以方便的进行维护
演示
一个在线演示可以在http://pagetalks.com/share/LocationSelect找到。
该演示实现了一个自动探测用户地理位置并自行选择的标准案例。
兼容性
我测试过如下浏览器:Safari5、Safari Mobile(iOS 4.0.1)、Firefox3、IE6、IE7、IE8、Opera10
下载
代码寄存在GitHub : http://github.com/RobinQu/LocationSelect-Plugin
安装
- (可选)引入jQuery脚本库,目前脚本仅在1.4.2的jQuery中进行过调试,推荐大家使用。同时,还可以使用Google的CDN进行加速:
- 由于需要用到JSON的解析器,脚本默认会调用JSON.parse方法来解析。如果你的项目里没有定义JSON.parse方法,请引用JSON.org的脚本。
- 现在已经不用手动引入第三方脚本了。
引入地理查询引擎(可选)- 本脚本是使用Google Map API V2以及MAXMIND的Javascript API进行联合查询实现确定用户地理信息的。随着Google Map的反向地址解析更为强大后,脚本会考虑减少外部脚本的依赖性。目前如果您需要使用自动检测功能,您必须引入这两个脚本: - 引入LocationSelect的脚本文件 –
- 在DOM Ready事件后调用,通常您应该传递响应数目的Select对象:
$(function() { $("select").LocationSelect({ name : "areas", labels :["请选择一个省份或直辖市", "请选择一个城市", "请选择一个区"] });
还可以选择使用非jQuery的初始方法:
var ls = new com.elfvision.kit.LocationSelect({ labels :["请选择一个省份或直辖市", "请选择一个城市", "请选择一个区"], elements : $("select").get() });
参数
如何定制
有很多同学想要进行定制操作,从1.1版本开始,就已经把大部分重要的算法给独立到单独的接口里面,方便大家定制。首先讲一下这个插件的工作原理。
Sequence Diagram
首先,插件会尝试使用ListHelper的fetch方法去取回所有要用的数据文件。默认情况下会访问ListHelper.dataUrl的地址,如果你不作任何配置,这个地址指向的是插件自带的areas_1.0.json。
当fetch方法返回之后,会执行一个回调函数。这个回调函数里回进行列表的初始划操作。
当列表都初始化完成,控件就已经可用了。如果自动探测的选项依然为true,就会继续接下来的探测逻辑。插件内置了根据IP判断地理位置的探测算法。
该算法是调用的Maxmind GEOCITY的API获得用户经纬度,然后使用Google Map的Geocoder WebService根据经纬度解析用户地理信息。然后利用返回结果去对列表进行“选择”。
可以看到还有个YQL的参与,这是Google Map V3的WebService已经不支持JSONP了,对跨域请求来说是噩梦。通过YQL作为一个Proxy返回的JSONP。
下面开始介绍如何进行深度定制。首先上一张Class Diagram。
Class Diagram
基本来说,通过定制所传入的ListHelper对象detector函数来控制该插件的功能。
Interface ListHelper
ListHelper是一个列表的工具接口。默认的ListHelper采用了Singleton的模式,但你可以选择不这么做。只要保证提供fetch和find方法即可。这两个方法必须实现如下操作:
- fetch方法接受一个回调函数,在把所需要的JSON基本数据取得了之后就必须会被执行。
- find方法根据传来level和id两个参数对fetch方法获得的数据进行查找进行记录的查找,必须返回一个装有记录的数组。
{ "id" : "112", "text" : "Foobar" }
注意该项目中所有的属性均为字符串。
你可以用fetch方法从后台取得数据(不管是啥数据,只要复合数据项目的结构规定)之后,根据这些数据实现find方法。
你可以传入的另外一个元素是detector函数。这个是执行自动选择的函数。默认的detector函数执行了地理位置的探测,但你可以实现你自得探测算法。只要最终使用LocationSelect.select()方法选择一组数据项。例如:
that.select(["湖北省",“武汉市”]);
这些值始终会根据List的传入顺序进行比对。如果List的数目大于给出的数组元素的数量,将不会对那些没有对应数值的List进行选择;如果传入的数值数组元素个数大于List个数,剩下的数组元素将会被抛弃。
通过传入自定义的ListHelper和detector,你可以完全自定义出类似于多级商品门类选择之类的联动菜单应用。也就不局限于选择一下地址而已了⋯⋯
更新日志