js三级联动(二)

先来看看最终效果,上图
在这里插入图片描述
数据参考以下网站:

  1. 中华人民共和国民政部
  2. 国家统计局
  3. 维基百科

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>&gt;</i>
      <i>&lt;</i>
    </a>
  </div>
</div>

css

按照这个图片自行发挥,也可以更改结构做成自己想要的样子
在这里插入图片描述

js

推荐思路:

  1. 点击事件显示隐藏联动框
  2. 首先显示省份列表,定义显示省份函数
  3. 点击导航显示对应 省 / 城市 / 区
  4. 点击某个省份,记录省的索引,显示对应城市列表,判断是否已经选择了省,并且城市还没选择,这时点击区无效
  5. 仿第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)
}

附加:好好学习天天向上

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值