原文地址→看过来

写在前面

前段时间写一个关于天气的东西,里面的省市区(县)城市选择让我很头疼,在网上搜索出来大都是借助插件或者第三方库,感觉这样做代码会很重,所以索性就把几种城市选择的方式实现一遍,以备日后的不时之需。这三种方法都是针对pc端的,并且都是使用原生js实现的,连jq都没使用,于是代码有点繁琐额(尴尬)。。。。不过还是让我把原理讲完吧。

源代码地址→传送门

预览地址→传送门

方法一:下拉选择框实现省市区(县)三级联动

  1. 用下拉框实现省市区三级联动是很常见的一种方式,也很方便。这里需要先了解下select的相关属性及其对象属性,请参考此文
  2. 先看下最终实现效果图:

  3. 思路介绍:
    • 页面加载时,动态获取省份列表并放到下拉菜单的下拉项中:

    /*自动加载省份列表*/
(function showProv() {
btn.disabled = true;
var len = provice.length;
for (var i = 0; i < len; i++) {
var provOpt = document.createElement('option');
provOpt.innerText = provice[i]['name'];
provOpt.value = i;
prov.appendChild(provOpt);
}
})();
  • 当点击省份列表中的某一项,此时触发省份下拉框的onchange事件,在onchange事件中根据前面所选的省份来显示对应城市。这里用到一个select的selectedIndex属性,从而获取刚刚点击的是哪个省份(生成省份列表时添加了value属性值):

    var val = obj.options[obj.selectedIndex].value;
//这里得到的是所选择省份在所有下拉项中为第几项
  • 当点击城市列表中的某一项时,原理同上(此处不赘述)

  • 选择城市时存在两种情况,如何城市选项下不存在县区,则直接将所选省市显示在输入框,否则依照上诉原理显示县区
    <!--方法是判断县区的length是否为0-->
var countryLen = provice[current.prov]["city"][val].districtAndCounty.length;
if(countryLen == 0){
addrShow.value = provice[current.prov].name + '-' + provice[current.prov]["city"][current.city].name;
return;
}
  • 最后点击县区后再按确定,则可将所选地点显示在输入框中。
  1. 注意:

    • 在未选中具体县区时,按钮为不可点状态
    • 具体的实现主要根据城市数据来进行更细的处理。
  2. 说明:
    • 这里使用的省市区数据来源于网络,不能保证真实性及完整性,仅供案例使用
    • 此处使用的数据类型为js数组,格式参考如下(完整版):
var provice = [
{
name: "北京市",
city: [
{
name: "北京市",
districtAndCounty: ["东城区", "西城区", "崇文区", "宣武区", "朝阳区", "丰台区", "石景山区", "海淀区", "门头沟区", "房山区", "通州区", "顺义区", "昌平区", "大兴区", "怀柔区", "平谷区", "密云县", "延庆县", "延庆镇"]
}
]
}, ...... {
name: "河北省",
city: [
{
name: "石家庄市",
districtAndCounty: ["长安区", "桥东区", "桥西区", "新华区", "裕华区", "井陉矿区", "辛集市", "藁城市", "晋州市", "新乐市", "鹿泉市", "井陉县", "微水镇", "正定县", "正定镇", "栾城县", "栾城镇", "行唐县", "龙州镇", "灵寿县", "灵寿镇", "高邑县", "高邑镇", "深泽县", "深泽镇", "赞皇县", "赞皇镇", "无极县", "无极镇", "平山县", "平山镇", "元氏县", "槐阳镇", "赵县", "赵州镇"]
}, ....... {
name: "邯郸市",
districtAndCounty: ["丛台区", "邯山区", "复兴区", "峰峰矿区", "武安市", "邯郸县",.....,"曲周县", "曲周镇"]
}
]
}
]

方法二:按级选中省市县/区

  1. 这种方式比上面的下拉框更好看点,操作也更方便点,不过大概的逻辑有点类似。所用省市区数据跟上面的一致。
  2. 先看看这种方式的效果图:

  3. 在页面加载时同样先显示出所有的省份列表(方法类似)

  4. 点击具体省份时,将省份列表替换成对应的城市列表,点击具体城市时显示对应县区,实现如下:
addrWrap.onclick = function (e) {     //将点击事件委托给列表的父元素
var n;
var e = e || window.event;
var target = e.target || e.srcElement;
if (target && target.nodeName == 'LI') {
/*先判断当前显示区域显示的是省市区的那部分*/
for (var z = 0; z < 3; z++) {
if (titleWrap[z].className == 'titleSel')
n = z;
}
/*显示的处理函数*/
switch (n) {
case 0:
showCity2(target.index); //点击的是省份中列表的某一项,接下来则显示城市列表
break;
case 1:
showCountry2(target.index); //点击的是城市列表中的某一项,接下来则显示县区列表
break;
case 2:
selectCountry(target.index); //点击具体的某个县区,则将该县区选择
break;
default:
showProv2();
}
}
};





5. 上面点击的每一步中将选中项的索引及值保存在一个对象中,以便最后点击确定按钮将选择的省市区显示在输入框中。

6. 当选择的城市不存在县区时处理跟第一种方式一致。

7. 当点击分类时,显示对应的内容,同时将保存的对象的值进行处理:

        //将事件委托给父元素,根据点击的分类进行处理(html的设置好li的value值)
if (target.value == '0') {
showProv2();
} else if (target.value == '1') {
showCity2(current2.prov);
} else {
showCountry2(current2.city);
}
  1. OK

方法三:按字母顺序选中城市

  1. 直接按字母的顺序选中城市这种方式比前两种更简单粗暴也较为简单,代码量也较少。
  2. 先看看这种方式的效果图:

  3. 页面加载时先显示热门城市

  4. 点击不同字母集,显示对应的城市列表
switch (index) {
case 0: //0为热门项
showHotCity();
break;
case 6: //6为最后一栏,字母集个数为2
showCitys(index, 2);
break;
default: //其余索引,字母集个数都为4
showCitys(index, 4);
}
function showCitys(index, m) {
//通过传入的参数截取城市数据的一部分为当前要显示的城市列表
var currentAll = cityAll.slice(4 * index - 3, 4 * index + m - 3); ..... //将动态生成的列表项放到显示区域
}
  1. 点击具体某一个城市时,将其显示在输入框中。

  2. 这种方式的城市数据跟前两种不同,来源于网上,不能保证真实性及完整性,仅供案例使用,数据格式如下(完整版):
var cityAll = [
{
name: "hot",
citys: ["北京", "上海", "广州", "深圳", "杭州", "南京", "成都", "重庆", "武汉", "长沙", "昆明"]
},
{
name: "A",
citys: ["阿坝", "阿拉善", "阿里", "安康", "安庆", "鞍山", "安顺", "安阳", "澳门"]
}, ...... {
name: "Z",
citys: ["杂多县", "赞皇县", "枣强县", "枣阳市", "枣庄",.......,资阳"]
}

7.完美~

小结

  1. 详细代码看上面给出了链接,有注释的额(firefox和chrome可正常显示)~
  2. 这几种实现方式为一己之见,欢迎大佬们指点,如有更好的可以告诉我,我来完善完善~
  3. 有人能告诉我怎么做gif图么?

原生JS实现省市区(县)三级联动选择的更多相关文章

  1. js之省市区(县)三级联动效果

    省市区(县)三级联动效果,是我们软件开发比较常用的,特别是对一些crm,erp之类,当然也包括其他的后台管理系统,基本都涉及到,今天贴出这个常用的,方便个人复用和大家使用 <!DOCTYPE h ...

  2. 省市区(县)三级联动代码(js 数据源)

    ylbtech-JavaScript-Utility:省市区(县)三级联动代码(js 数据源) 省市区(县)三级联动代码(js 数据源) 1.A,源代码(Source Code)返回顶部 1.A.1, ...

  3. vue仿京东省市区三级联动选择组件

    工作中需要一个盒京东购物车地址选择相似的一个省市区三级联动选择组件,google查了下都是下拉框形式的,于是自己写了一个,希望对使用vue开发项目的朋友有帮助,显示效果如下:使用vue2.0开发 ht ...

  4. JQUERY省、市、县城市联动选择

    JQUERY 插件开发——CITYLINKAGE(省.市.县城市联动选择) 第一部分:背景   开发源于需求,本次城市联动选择插件算是我写插件的一个特例吧,不是我目前工作需要些的,算是兴趣驱使吧.之前 ...

  5. 中国省市区地址三级联动jQuery插件 案例下载

    中国省市区地址三级联动jQuery插件 案例下载 distpicker 是一款可以实现中国省市区地址三级联动jQuery插件.它使用简单,简单设置即可完成中国省市区地址联动效果. 安装 可以通过npm ...

  6. JQuery实现省市区的三级联动

    JQuery实现省市区的三级联动 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "h ...

  7. JavaScript实现省市区的三级联动

    JavaScript实现省市区的三级联动 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" &qu ...

  8. Jquery 插件开发——citylinkage(省、市、县城市联动选择)

    第一部分:背景  开发源于需求,本次城市联动选择插件算是我写插件的一个特例吧,不是我目前工作需要些的,算是兴趣驱使吧.之前呢,一直想写这个插件,然后错过了一个写这个插件的机会(这个得回顾到很久以前了. ...

  9. 中国省市区地址三级联动插件---jQuery Distpicker

    插件描述:distpicker是一款可以实现中国省市区地址三级联动jQuery插件.它使用简单,简单设置即可完成中国省市区地址联动效果. [官网]https://fengyuanchen.github ...

随机推荐

  1. 【软工实践】第四次作业--爬虫结合WordCount

    结对同学博客链接 本次作业博客链接 github项目地址 具体分工 我主要负责用python写爬虫部分,他负责C++部分 PSP表格 解题思路 代码的核心思路是利用爬虫,爬取论文网址,之后吧对应信息( ...

  2. 团队Alpha冲刺(一)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示组内 ...

  3. Alpha 冲刺5

    队名:日不落战队 安琪(队长) 今天完成的任务 组织第五次站立式会议(半冲刺总结交流会). 完成草稿箱前端界面. 明天的计划 回收站前端界面. 尝试去调用数据. 还剩下的任务 信息修改前端界面. 遇到 ...

  4. 【beta】nice!-------约吧NABCD

    小组名称:nice! 组长:李权 成员:于淼  刘芳芳韩媛媛 宫丽君 项目内容:约跑app(约吧) 约吧APP下载地址: 百度云:链接:http://pan.baidu.com/s/1jHNBR3g ...

  5. jquery中on绑定click事件在苹果手机失效问题解决(巨坑啊)

    描述:用一个div写一个按钮,并给这个按钮添加一个点击事件,在安卓机器上一切正常,但是在苹果机型上会出现点击事件失效. <!DOCTYPE html> <html lang=&quo ...

  6. HDU4054_Hexadecimal View

    水题.直接八位八位地枚举即可. 注意控制输出,注意读数的时候要把s中的全部元素置零. #include <iostream> #include <cstdio> #includ ...

  7. C++解析-外传篇(2):函数的异常规格说明

    0.目录 1.异常规格说明 2.unexpected() 函数 3.小结 1.异常规格说明 问题: 如何判断一个函数是否会抛出异常,以及抛出哪些异常? C++提供语法用于声明函数所抛出的异常 异常声明 ...

  8. 洛谷 P2763 试题库问题(网络流24题之一)

    题目描述 «问题描述: 假设一个试题库中有n道试题.每道试题都标明了所属类别.同一道题可能有多个类别属性.现要从题库中抽取m 道题组成试卷.并要求试卷包含指定类型的试题.试设计一个满足要求的组卷算法. ...

  9. 在 QML 中创建 C++ 导入类型的实例

    在 QML 中创建 C++ 导入类型的实例 文件列表: Project1.pro QT += quick CONFIG += c++ CONFIG += declarative_debug CONFI ...

  10. [洛谷P5190][COCI 2010] PROGRAM

    题目大意:给你$k(k\leqslant10^6)$个数,$f(x)$表示$x$的约数在$k$个数中出现的次数,在这任何数都是$0$的约数.$m(m\leqslant10^6)$次询问,每次给出$l, ...