news 2026/8/28 7:00:58

简单的下拉框省市联动

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
简单的下拉框省市联动

前言

做后台表单的时候,经常会遇到省份、城市二级联动下拉框。选省份,城市自动刷新对应列表,没选省份的时候城市框提示 “请先选择省份”。

网上常见两种数据格式:

  1. 数组包对象格式:[{province:'xx',city:[]}]
  2. 对象格式:{"省份名":[城市数组]}

本文用第二种对象格式来实现,代码简单易懂,适合新手学习,基于 jQuery 完成。

前提:页面需要引入 jQuery 库,否则 $ 符号会报错。

最终效果

  1. 页面加载完成,省份下拉渲染全部省份,默认提示:请选择省份
  2. 城市下拉初始提示:请先选择省份
  3. 切换省份,城市下拉自动更新为该省下所有城市
  4. 切回 “请选择省份”,城市下拉重置提示文字

HTML 结构

就两个 select 选择框,class 分别为provincecity

<!--省份下拉--> <select class="province"></select> <!--城市下拉--> <select class="city"> <option value="">请先选择省份</option> </select>

JS 完整代码

数据用对象,key 是省份名称,value 是该省份下城市数组。

// 省市数据:对象格式 key=省份,value=城市数组 let city_data = { "广东省": [ "广州市", "深圳市", "珠海市", "汕头市", "佛山市", "韶关市", "湛江市", "肇庆市", "江门市", "茂名市" ], "浙江省": [ "杭州市", "宁波市", "温州市", "嘉兴市", "湖州市", "绍兴市", "金华市", "衢州市", "舟山市", "台州市" ], "江苏省": [ "南京市", "无锡市", "徐州市", "常州市", "苏州市", "南通市", "连云港市", "淮安市", "盐城市", "扬州市" ], "山东省": [ "济南市", "青岛市", "淄博市", "枣庄市", "东营市", "烟台市", "潍坊市", "济宁市", "泰安市", "威海市" ], "河南省": [ "郑州市", "开封市", "洛阳市", "平顶山市", "安阳市", "鹤壁市", "新乡市", "焦作市", "濮阳市", "许昌市" ] } $(document).ready(function () { //页面加载完毕,先渲染省份 renderProvince(city_data) }) /** * 渲染省份下拉框 * @param {Object} data 省市对象数据 */ function renderProvince(data) { let province_html = "" // 判断对象是否有属性 if (data && Object.keys(data).length > 0) { // 默认选项 province_html += `<option value="请选择省份">请选择省份</option>` // for...in遍历对象,拿到每一个省份key for (let key in data) { province_html += ` <option value="${key}">${key}</option> ` } //把拼接好的html塞进省份select $('.province').html(province_html) } } //省份下拉发生改变事件 $('.province').change(function () { //拿到选中的省份value let selected_province = $(this).val() renderCity(selected_province) }) /** * 根据选中省份渲染城市 * @param {String} data 选中的省份名称 */ function renderCity(data) { //直接对象取值,拿到对应省份的城市数组 let filterdata = city_data[data] let city_html = "" //判断城市数组存在并且长度大于0 if (filterdata && filterdata.length > 0) { for (let i = 0; i < filterdata.length; i++) { city_html += `<option value="${filterdata[i]}">${filterdata[i]}</option>` } $('.city').html(city_html) } else { // 没匹配到省份,重置提示 city_html = `<option value="">请先选择省份</option>` $('.city').html(city_html) } }

代码拆解

1、数据格式说明

let city_data = { "河南省":["郑州市","新乡市"] }

对象格式好处:根据省份名字直接city_data["河南省"]就能取出城市数组,不用循环 find 查找,写起来省事。 对比数组套对象的写法,少写一次 find 筛选,代码更简短。

2、renderProvince 渲染省份函数

  • Object.keys(data):拿到对象所有 key,判断对象不是空对象。
  • for...in循环对象,把每一个省份拼接成<option>
  • 使用$('.province').html()直接覆盖下拉里面所有选项。

3、change 监听省份下拉改变

只要用户切换省份下拉,就触发 change 事件,获取当前选中省份的值,调用渲染城市的函数。

4、renderCity 渲染城市函数

  • city_data[data]:直接通过省份名称取出城市列表。
  • 如果取到城市数组,循环拼接城市 option 渲染。
  • 如果没有取到(比如选中默认项 “请选择省份”),城市下拉重置提示 “请先选择省份”。

需要注意的坑

  1. 一定要引入 jQuery,不然$()直接报错。
  2. 省份value必须和对象的 key 完全一模一样,文字不能错字,否则拿不到城市数据。
  3. html()方法是覆盖原有内容,会把 select 内部全部替换,所以每次都要完整拼接 option。
  4. 当选中 “请选择省份” 时,city_data["请选择省份"]结果是undefined,会走进 else 分支,城市框重置,刚好符合业务需求。

拓展

  1. 如果后端返回数组套对象格式[{province:'',city:[]}],那就要用.find()去找对应省份。
  2. 如果要做三级联动(省市区),逻辑一模一样,多写一层渲染函数。
  3. 如果是从接口拿异步数据,要等接口返回之后再调用renderProvince(),不能页面一加载就执行。

完整可运行 demo

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>二级下拉联动</title> <script src="https://cdn.jsdelivr.net/npm/jquery@3.7.1/dist/jquery.min.js"></script> </head> <body> <select class="province"></select> <select class="city"> <option value="">请先选择省份</option> </select> <script> let city_data = { "广东省": [ "广州市", "深圳市", "珠海市", "汕头市", "佛山市", "韶关市", "湛江市", "肇庆市", "江门市", "茂名市" ], "浙江省": [ "杭州市", "宁波市", "温州市", "嘉兴市", "湖州市", "绍兴市", "金华市", "衢州市", "舟山市", "台州市" ], "江苏省": [ "南京市", "无锡市", "徐州市", "常州市", "苏州市", "南通市", "连云港市", "淮安市", "盐城市", "扬州市" ], "山东省": [ "济南市", "青岛市", "淄博市", "枣庄市", "东营市", "烟台市", "潍坊市", "济宁市", "泰安市", "威海市" ], "河南省": [ "郑州市", "开封市", "洛阳市", "平顶山市", "安阳市", "鹤壁市", "新乡市", "焦作市", "濮阳市", "许昌市" ] } $(document).ready(function () { renderProvince(city_data) }) function renderProvince(data) { let province_html = "" if (data && Object.keys(data).length > 0) { province_html += `<option value="请选择省份">请选择省份</option>` for (let key in data) { province_html += `<option value="${key}">${key}</option>` } $('.province').html(province_html) } } $('.province').change(function () { let selected_province = $(this).val() renderCity(selected_province) }) function renderCity(data) { let filterdata = city_data[data] let city_html = "" if (filterdata && filterdata.length > 0) { for (let i = 0; i < filterdata.length; i++) { city_html += `<option value="${filterdata[i]}">${filterdata[i]}</option>` } $('.city').html(city_html) } else { city_html = `<option value="">请先选择省份</option>` $('.city').html(city_html) } } </script> </body> </html>

复制全部代码保存 html 文件,直接浏览器打开就可以看到效果。

总结

二级联动核心逻辑就三步:

  1. 页面初始化渲染第一级下拉(省份)
  2. 监听第一级下拉 change 事件,拿到选中值
  3. 根据选中值过滤数据,渲染第二级下拉(城市)
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/28 6:58:43

掼蛋AI双轨训练:模仿学习+强化学习实战指南

简介&#xff1a;掼蛋作为典型的多人协作博弈场景&#xff0c;是检验多智能体决策能力的重要基准——它融合不完全信息、隐式通信与长期协作等核心挑战。其技术本质在于构建可泛化的状态表征、建模队友意图并优化联合收益。基于行为克隆的模仿学习能快速注入人类先验知识&#…

作者头像 李华
网站建设 2026/8/28 6:57:55

KUKA Simpro运动单元创建:从静态模型到可仿真机器人的核心步骤

1. 项目概述&#xff1a;从“模型”到“单元”的关键一步在上一篇文章里&#xff0c;我们完成了KUKA Simpro 3.0.3的基础环境搭建&#xff0c;并成功导入了机器人本体模型。看着那个酷炫的机械臂在场景里摆着造型&#xff0c;感觉离仿真就差临门一脚了&#xff0c;对吧&#xf…

作者头像 李华
网站建设 2026/8/28 6:57:16

超越模型:构建可靠Agent系统的六项工程化契约与实践指南

超越模型&#xff1a;构建可靠Agent系统的六项工程化契约与实践指南 引言&#xff1a;从"Demo"到"Production"的鸿沟 在过去的一年里&#xff0c;我们见证了LLM&#xff08;大语言模型&#xff09;能力的飞速发展&#xff0c;基于其构建的Agent应用也层出不…

作者头像 李华
网站建设 2026/8/28 6:55:01

人形机器人在化工应急响应场景中的应用(下)

三、人形机器人&#xff09;强腐蚀环境下的关节密封材料选择在强腐蚀环境下&#xff0c;为人形机器人关节选择合适的密封材料至关重要。这不仅能保护内部精密部件&#xff0c;也直接关系到机器人的使用寿命和可靠性。目前&#xff0c;氟橡胶、聚偏二氟乙烯&#xff08;PVDF&…

作者头像 李华
网站建设 2026/8/28 6:54:06

兼职销售获客效率分析:企业获客软件的实际使用体验

从时间成本和筛选精度的角度&#xff0c;分析企业获客软件对兼职销售的适配性。兼职做销售&#xff0c;最大的问题是时间不够用&#xff0c;怎么破&#xff1f;兼职的最大瓶颈就是时间&#xff0c;白天有主业&#xff0c;只能挤晚上或者周末的时间联系客户&#xff0c;如果还要…

作者头像 李华
网站建设 2026/8/28 6:54:04

工业厂房项目安全生产动画结合延时摄影的实操经验

安全文明生产的警示教育动画&#xff0c;用于大型厂房建设&#xff0c;完全可以和施工延时摄影相结合&#xff0c;实拍记录建设成果&#xff0c;三维安全生产动画推演隐患&#xff0c;二者相辅相成&#xff0c;长沙尚格影视结合星邦重工新工厂项目&#xff0c;讲下这套组合方案…

作者头像 李华