<!DOCTYPE html>  
<html lang="en">  

<head>  
  <meta charset="UTF-8" />  
  <meta name="viewport" content="width=device-width, initial-scale=1" />  
  <title>纯 JS 楼层切换控件</title>  
  <style>  
    .card_floor_control {  
      user-select: none;  
      position: absolute;  
      top: 100px;  
      right: calc(25% + 10px);  
      width: 100px;  
      height: auto;  
      font-family: Arial, sans-serif;  
    }  

    .floor_control {  
      position: relative;  
      cursor: pointer;  
      width: 100px;  
      height: 40px;  
      background-color: rgba(34, 91, 153, 0.3);  
      display: flex;  
      align-items: center;  
      justify-content: center;  
      color: #ffffff;  
      border-radius: 4px;  
      user-select: none;  
    }  

    .triangle:after {  
      content: '';  
      display: inline-block;  
      margin-left: 20px;  
      width: 10px;  
      height: 10px;  
      border-top: 1px solid #ffffff;  
      border-right: 1px solid #ffffff;  
      transform: rotate(135deg);  
      -webkit-transform: rotate(135deg);  
    }  

    .all_building_floor {  
      position: relative;  
      margin-top: 10px;  
      display: none;  
      flex-direction: column;  
      right: 0px;  
    }  

    .box_item_bf {  
      display: flex;  
      align-items: center;  
      justify-content: center;  
      font-size: 18px;  
      position: relative;  
      user-select: none;  
    }  

    .floor_box {  
      cursor: pointer;  
      color: rgb(108, 111, 113);  
      --c: rgb(108, 111, 113);  
      --n: 4;  
      --t: 2px;  
      --d: 45deg;  
      aspect-ratio: 1;  
      width: 60px;  
      height: 60px;  
      border-radius: 50%;  
      background-color: rgb(1, 6, 19);  
      margin-bottom: 10px;  
      position: relative;  
    }  

    .floor_box::after {  
      content: "";  
      position: absolute;  
      top: 2.5px;  
      left: 2.5px;  
      width: 55px;  
      height: 55px;  
      border-radius: 50%;  
      padding: var(--t);  
      background: var(--c);  
      -webkit-mask:  
        linear-gradient(#0000 0 0) content-box,  
        repeating-conic-gradient(from calc(var(--d)/2), #000 0 calc(360deg/var(--n) - var(--d)), #0000 0 calc(360deg/var(--n)));  
      -webkit-mask-composite: source-in;  
      mask:  
        linear-gradient(#0000 0 0) content-box,  
        repeating-conic-gradient(from calc(var(--d)/2), #000 0 calc(360deg/var(--n) - var(--d)), #0000 0 calc(360deg/var(--n)));  
      mask-composite: intersect;  
    }  

    .activate_box {  
      cursor: pointer;  
      color: #fff;  
      --c: #fff;  
      --n: 4;  
      --t: 2px;  
      --d: 45deg;  
      aspect-ratio: 1;  
      width: 60px;  
      height: 60px;  
      border-radius: 50%;  
      background-color: rgb(1, 6, 19);  
      margin-bottom: 10px;  
      position: relative;  
    }  

    .activate_box::after {  
      content: "";  
      position: absolute;  
      top: 2.5px;  
      left: 2.5px;  
      width: 55px;  
      height: 55px;  
      border-radius: 50%;  
      padding: var(--t);  
      background: var(--c);  
      -webkit-mask:  
        linear-gradient(#0000 0 0) content-box,  
        repeating-conic-gradient(from calc(var(--d)/2), #000 0 calc(360deg/var(--n) - var(--d)), #0000 0 calc(360deg/var(--n)));  
      -webkit-mask-composite: source-in;  
      mask:  
        linear-gradient(#0000 0 0) content-box,  
        repeating-conic-gradient(from calc(var(--d)/2), #000 0 calc(360deg/var(--n) - var(--d)), #0000 0 calc(360deg/var(--n)));  
      mask-composite: intersect;  
      animation: rotate 5s linear infinite;  
    }  

    @keyframes rotate {  
      from {  
        transform: rotate(0deg);  
      }  

      to {  
        transform: rotate(360deg);  
      }  
    }  
  </style>  
</head>  

<body>  
  <div class="card_floor_control">  
    <div class="floor_control" id="floorControl">  
      全部<span class="triangle"></span>  
    </div>  
    <div class="all_building_floor" id="allBuildingFloor"></div>  
  </div>  

  <script>  
    (function () {  
      const arrData = [  
        { title: '全部', id: 'all' },  
        {  
          title: 'A栋', id: 'A', list: [  
            { title: '3F', id: '3' },  
            { title: '2F', id: '2' },  
            { title: '1F', id: '1' }  
          ]  
        },  
        {  
          title: 'B栋', id: 'B', list: [  
            { title: '3F', id: '3' },  
            { title: '2F', id: '2' },  
            { title: '1F', id: '1' }  
          ]  
        },  
        {  
          title: 'C栋', id: 'C', list: [  
            { title: '4F', id: '4' },  
            { title: '3F', id: '3' },  
            { title: '2F', id: '2' },  
            { title: '1F', id: '1' }  
          ]  
        },  
        {  
          title: 'D栋', id: 'D', list: [  
            { title: '2F', id: '2' },  
            { title: '1F', id: '1' }  
          ]  
        }  
      ]  

      // 当前选中项id 和 title  
      let currentId = 'all';  
      let currentTitle = '全部';  

      const floorControl = document.getElementById('floorControl');  
      const allBuildingFloor = document.getElementById('allBuildingFloor');  

      // 控制楼层列表容器显示/隐藏  
      let showList = false;  

      floorControl.addEventListener('click', () => {  
        showList = !showList;  
        if (showList) {  
          allBuildingFloor.style.display = 'flex';  
          // 切换显示当前选中项对应的列表  
          renderList();  
        } else {  
          allBuildingFloor.style.display = 'none';  
        }  
      });  

      // 渲染列表区域  
      function renderList() {  
        allBuildingFloor.innerHTML = '';  

        // 找到当前id对应的item，和列表数据  
        let listData = [];  

        if (currentId === 'all') {  
          // 如果是全部，展示顶层选项  
          listData = arrData;  
        } else {  
          const currentBuilding = arrData.find(item => item.id === currentId);  
          if (currentBuilding && currentBuilding.list) {  
            listData = currentBuilding.list;  
          } else {  
            // 防止找不到对应list  
            listData = [];  
          }  
        }  

        listData.forEach(item => {  
          const div = document.createElement('div');  
          div.classList.add('box_item_bf');  

          if (item.id === currentId) {  
            div.classList.add('activate_box');  
          } else {  
            div.classList.add('floor_box');  
          }  

          div.textContent = item.title;  

          div.addEventListener('click', (e) => {  
            e.stopPropagation();  // 阻止事件冒泡，避免触发外层点击  
            switchoverItem(item);  
          });  

          allBuildingFloor.appendChild(div);  
        });  
      }  

      // 切换选中项  
      function switchoverItem(item) {  
        // 如果点了目前已经选中的项，列表隐藏  
        if (item.id === currentId) {  
          showList = false;  
          allBuildingFloor.style.display = 'none';  
          return;  
        }  

        currentId = item.id;  
        currentTitle = item.title;  

        // 改变按钮显示文字  
        floorControl.childNodes[0].nodeValue = currentTitle;  

        // 如果选中的是“全部”，则展示arrData顶层数据  
        if (currentId === 'all') {  
          // 当前激活项就是全部  
          renderList();  
        } else {  
          // 判断当前id是否是顶层id，如果在顶层arrData里则显示对应list，否则显示arrData顶层选项  
          const isTopLevel = arrData.some(it => it.id === currentId);  

          if (isTopLevel) {  
            renderList();  
          } else {  
            // 当前选中的是具体楼层，这时列表显示 arrData 顶层，方便切换楼栋  
            currentId = 'all'; // 也可以这样处理，或者直接关闭列表  
            currentTitle = '全部';  
            floorControl.childNodes[0].nodeValue = currentTitle;  
            showList = false;  
            allBuildingFloor.style.display = 'none';  
          }  
        }  
      }  

      // 初始化显示  
      floorControl.childNodes[0].nodeValue = currentTitle;  

      // 说明：初始时列表隐藏，点击按钮显示顶层选项，也就是arrData。  

    })();  
  </script>  

</body>  

</html>