先来看看最终效果,上图
数据参考以下网站:
html
<div class="ui-city">
<!-- 切换显示隐藏框 -->
<div class="ui-city-toggle">
<a class="address-placement">
<span id="province" class="province">省、自治区、直辖市</span>
<span id="city" class="city">地级市、地区、自治州、盟</span>
<span id="region" class="region">市辖区、县级市、县…</span>
</a>
<b class="arr"></b>
</div>
<div class="ui-city-group">
<div class="ui-city-group-content">
<!-- 导航标签 -->
<ul class="nav-tabs clearfix">
<li class="active" value="0">
<!-- value值是为了点击之后获取的索引值 -->
<p>
<a>请选择省</a>
<b class="arr"></b>
</p>
</li>
<li value="1">
<p>
<a>请选择市</a>
<b class="arr"></b>
</p>
</li>
<li value="2">
<p>
<a>请选择县区</a>
<b class="arr"></b>
</p>
</li>
</ul>
<!-- 面板 -->
<div class="tab-content">
<ul class="tab-panel">
<li></li>
</ul>
</div>
</div>
<!-- 关闭按钮 -->
<a href="javascript:;" class="ui-city-close">
<i>></i>
<i><</i>
</a>
</div>
</div>
css
按照这个图片自行发挥,也可以更改结构做成自己想要的样子
js
推荐思路:
- 点击事件显示隐藏联动框
- 首先显示省份列表,定义显示省份函数
- 点击导航显示对应 省 / 城市 / 区
- 点击某个省份,记录省的索引,显示对应城市列表,判断是否已经选择了省,并且城市还没选择,这时点击区无效
- 仿第4步类推类推
1、控制显示隐藏
uiCityToggle.addEventListener('click', () => {
uiCity.classList.toggle('active')
}, false)
uiCityClose.addEventListener('click', () => {
uiCity.classList.remove('active')
}, false)
2、默认显示省
showProvinces()
function showProvinces() {
tabPanelList.innerHTML = '' //清空面板数据
for (const key in provinces) {
if (provinces.hasOwnProperty(key)) {
let span = document.createElement('span')
let a = document.createElement('a')
a.innerText = provinces[key].name
a.index = key // 循环为 a 赋值索引
if (newProvTargetIndex === Number.parseInt(a.index)) { // 如果点击的省的索引跟a的索引相等,则显示高亮
a.classList.add('on')
}
span.appendChild(a)
tabPanelList.appendChild(span)
}
}
console.log(newProvTargetIndex, newProvTargetName, newCityTargetIndex, newCityTargetName,newRegionTargetIndex, newRegionTargetName)
}
3、点击导航显示对应 省 / 城市 / 区
navTabs.addEventListener('click', (e) => { //导航标签事件委托
let target = e.target
while (target !== navTabs) {
if (target.nodeName.toLowerCase() === 'li') {
navTabsList[navTabsListIndex].classList.remove('active')
navTabsListIndex = Number.parseInt(target.getAttribute('value')) //获取的是字符串,要转为number
target.classList.add('active')
switch (navTabsListIndex) { //根据导航标签索引判断应该显示 省面板 / 城市面板 / 区面板
case 0:
showProvinces()
break
case 1:
showCitys()
break
case 2:
showRegions()
break
}
break
}
target = target.parentNode
}
return
}, false)
4、点击省面板,显示城市列表
tabPanel.addEventListener('click', (e) => { //面板事件委托
let target = e.target
if (target.nodeName.toLowerCase() === 'a') {
switch (navTabsListIndex) { //看看当前在那个导航标签上,如果是省标签上,点击选择某个省之后应该自动跳转到城市
case 0:
newProvTargetIndex = Number.parseInt(target.index) // 记录当前点击的是哪个省的索引
showCitys()
break
case 1:
newCityTargetIndex = Number.parseInt(target.index) // 记录当前点击的是哪个城市的索引
showRegions()
break
case 2:
newRegionTargetIndex = Number.parseInt(target.index) // 记录当前点击的是哪个区的索引
selectRegion()
break
}
}
}, false)
function showCitys() {
newProvTargetName = provinces[newProvTargetIndex].name // 获取点击的省的名字
navTabsListA[0].innerText = newProvTargetName // 赋值到导航省的名字
tabPanelList.innerHTML = ''
navTabsList[0].classList.remove('active')
navTabsList[1].classList.add('active')
navTabsListIndex = 1
if (newProvTargetIndex !== tempProvTargetIndex) { // 判断当前点击省跟上一次点击省的索引是否一样,如果不一样,要重置城市,区
navTabsListA[1].innerText = '请选择市'
navTabsListA[2].innerText = '请选择县区'
newCityTargetIndex = null
newCityTargetName = null
newRegionTargetIndex = null
newRegionTargetName = null
}
if (newProvTargetName && newCityTargetName === null) { // 判断是否已经选择了省,并且城市还没选择,这时点击区无效
navTabsList[0].style.cssText = `pointer-events: auto;`
navTabsList[1].style.cssText = `pointer-events: auto;`
navTabsList[2].style.cssText = `pointer-events: none;`
}
for (const key in provinces[newProvTargetIndex].citys) { // 根据已选择省的索引,获取对应的城市列表
if (provinces[newProvTargetIndex].citys.hasOwnProperty(key)) {
let span = document.createElement('span')
let a = document.createElement('a')
a.innerText = provinces[newProvTargetIndex].citys[key].name
a.index = key
if (newCityTargetIndex === Number.parseInt(a.index)) {
a.classList.add('on')
}
span.appendChild(a)
tabPanelList.appendChild(span)
}
}
tempProvTargetIndex = newProvTargetIndex // 将选择的省的索引赋值给临时省索引(上一次点击省的索引)
console.log(newProvTargetIndex, newProvTargetName, newCityTargetIndex, newCityTargetName,newRegionTargetIndex, newRegionTargetName)
}
附加:好好学习天天向上