基于闭包和JSON的省市区联动菜单的实现
2020-11-28王爱华
王爱华
摘 要:利用网页中嵌套的div元素结合样式的相对定位和绝对定位技术,通过访问JSON数据以及应用脚本中闭包的特点,制作一款简单实用的省市区联动菜单。
关键词:定位;JSON数据;闭包;省市区联动
中图分类号:TP393 文献标识码:A 文章编号:1671-2064(2020)12-0057-02
省市区联动在很多购物网站中使用,用户填写收件地址时,通过省市区联动功能选择省份、地市和区镇,用起来非常方便。本文将使用网站开发中的定位技术、脚本中的闭包技术,结合访问JSON数据来实现一款美观方便的省市区联动菜单。
1 运行效果说明
页面初始运行时,只显示图1①的内容,鼠标指向此处时,显示图1②的部分,此时若是直接点击请选择地市或者请选择区镇,打开的内容区都为空,若是点击请选择省份,则显示图1下方所有省份以供用戶选择。
若从所示省份中选择山东省,修改选项卡名称为山东省之后,直接跳转到请选择地市区域,显示山东省所有地市,若选择济南市,则修改选项卡名称后,直接跳转到请选择区镇区域,显示济南市所有区镇,若选择历下区,则将选项卡名称改为历下区,至此,一轮选择完毕,图1①内容变成“山东省/济南市/历下区”,鼠标离开之后,将收起下面所有的信息,只显示选择的结果。
2 页面元素的结构和样式要求
生成页面元素的代码如下。
类名为dW的元素是顶层元素,宽400像素,相对定位。
Id为tabW的元素,设置图1①所示界面,高20像素,填充5像素,边框1像素灰色,绝对定位,z轴取值为2,表示将其置于divW元素的前方,纵横坐标为0,该div占据纵坐标空间为0到31像素。
Id为divW的元素,宽380像素,最小高度60像素,设置选项卡区,显示相应的省份、地市或者区镇,高度需要跟随变化;下填充0,其余填充10像素,边框1像素灰色,白色背景用于遮挡后面内容,绝对定位,z轴为1,纵坐标31像素,初始状态隐藏。
当鼠标指向divW时,使用:hover和子元素选择符设置tabW的下边框为白色,设置divW显示,通过tabW的白色下边框覆盖divW上边框中相应部分,达到图1①和②上下一体的效果。
选项卡区使用类名divT定义,宽380像素,高34像素,绝对定位,z轴为2。每个选项卡使用类名tab定义,高20像素,填充5像素,右边距5像素,边框2像素灰色,下边框2像素暗红色,向左浮动,字号10pt,文本行高20像素。选中的选项卡使用类名tabS定义,边框2像素,颜色暗红,下边框2像素白色,做到选项卡和下面内容区连为一个整体。
每个内容区使用类名cont定义,宽380像素,上填充10像素,边距auto,上边框2像素暗红色,绝对定位,z轴为1,纵坐标42像素,这是因为盒子divW有10像素上填充,每个选项卡元素总高度为34像素,所以选项卡在divW中占据的纵坐标范围为10到43像素,内容区的2像素上边框需要与选项卡的下边框重合,重合的两个像素为42像素和43像素,所以内容区的纵坐标需要设置为42像素。
省份、地市和区镇三个内容区除了使用类名cont之外,分别应用了prov、city和area类名。内容区中显示的所有省份、地市或者区镇名称,都使用span元素定界,通过浮动将span设置为横向排列的块元素,宽95像素,高30像素,字号10pt,蓝色文本,鼠标手状。
3 JSON数据的定义和访问
省市区联动功能中,使用的省市区名称非常多,需要定义JSON数据。为了能够让读者理解数据的结构和定义方式,使用图2展示了北京市的数据。
数组中每一个元素都是一个对象,对象拥有name和city两个属性,name取值为省份名称,city取值又是一个数组,数组中每个元素都是一个对象,对象拥有name和area两个属性,name取值为地市名称,area取值是一个一维数组,数组元素内容是当前地市下面所有区镇名称。对于直辖市来说,city数组只有一个对象元素,对于省份来说,city数组中对象元素的个数取决于地市的个数。使用$.getJSON()方法读取JSON数据之后保存在全局变量city中,方便下面操作。
4 使用闭包实现省市区联动功能
首先对数组city进行遍历,将所有省份名称使用span标记定界之后连接在一起,保存在变量contP中,为接下来显示省份做好准备。
4.1 点击选项卡时的功能设置
定义选择省份、地市和区镇三个选项卡的点击事件处理函数$(“.tab”).click(function(){…}),该函数是顶层函数,功能如下。
使用jQuery的移除类名方法去掉所有选项卡中引用的tabS类名,恢复其初始状态,同时隐藏所有内容区;之后为当前选项卡添加类名tabS,将其设置为选中状态,获取該选项卡索引,根据索引设置相应内容区为显示状态;为保证divW的高度能够跟随不同内容区内容多少变化,需要判断选项卡的索引,若是0,表示点击的是请选择省份选项卡,将变量contP的内容设置为内容区prov的内容,获取该内容区的高度,增加60像素之后,重新设置为divW的高度;若当前选项卡索引是1或者2,也就是点击的是请选择地市或请选择区镇时,分别获取city和area内容区的高度,增加60像素之后设置为divW的高度。
4.2选择省份
定义省份的事件处理函数$(“.prov>span”).click(function(){…}),该函数是选项卡点击事件函数的闭包,功能如下。
获取点击的省份名称保存在变量provT中,替换掉省份选项卡的内容。获取该省份的索引,保存在变量provI中,通过该索引获取省份下面的地市;完成该操作之后,使用触发器方法触发地市选项卡的click事件;每次重新选择省份之后,需要清除之前选择过的地市和区镇信息,恢复原“请选择地市”和“请选择区镇”内容,清除之前的区镇选项卡对应的内容区的内容;遍历当前选中省份的所有地市,以span元素连接在一起放在变量contC中,将contC内容作为内容区city的内容,获取内容区city的高度,增加60像素之后,设置为divW的高度。
4.3 选择地市
定义地市的事件处理函数$(“.city>span”).click(function(){…}),该函数是省份点击事件函数的闭包,功能如下。
获取点击的地市名称保存在变量cityT中,替换掉地市选项卡的内容。获取当前地市的索引,保存在变量cityI中,通过该索引获取地市下面的区镇;完成该操作之后,使用触发器方法触发区镇选项卡的click事件。每次重新选择地市之后,需要重新选择区镇,因此要将之前选择的区镇信息去掉,设置区镇选项卡的文本为“请选择区镇”;遍历将当前选中地市的所有区镇,以span元素内容形式连接在一起放在变量contA中,将contA内容作为内容区area的内容,获取内容区area的高度,增加60像素之后,设置为divW的高度。
4.4选择区镇
定义区镇的事件处理函数$(“.area>span”).click(function(){…}),该函数是地市点击事件函数内部的闭包,功能如下。
获取点击的区镇名称保存在变量areaT中,替换掉区镇选项卡的内容;设置变量selT的取值为选择的结果,例如“山东省/济南市/历下区”,作为选项卡“请选择省份、地市和区镇”的内容。
5 结语
本文根据闭包的功能特点,使用四层嵌套函数完成省市区联动菜单,先点击省份选项卡,在显示的省份信息中点击所属的省份名称,点击省份下面的地市名称,点击地市下面的区镇名称,每一层函数的功能必须基于上一层函数的结果。选择了一次省份之后,可以反复重新选择该省份下面的地市和地市下面的区镇,通过闭包有效保留了父函数中局部变量的取值。
使用该方案实现的省市区联动菜单,可以嵌入在页面中任意一个位置,结构清晰,应用方便。