h5菜单(横向滚动、点击居中、更多级联居中)

 描述

基于vue的移动端菜单,菜单可以横向滚动和展开,支持点击居中选择导航

效果

 页面

<div class="main-top">
    <div class="main-block">
      <div class="flex-row">
        <div class="flex-cell" v-for="(item, index) in state.categoryDataList" :key="item.id">
          <a
            href="#"
            :class="state.categoryid == item.id ? 'active' : ''"
            @click.prevent="handleClickMenu(item.id, index)"
          >
            <img :src="item.imgUrl" />
            <span>{{ item.categoryName }}</span>
          </a>
        </div>
      </div>
    </div>
    <div class="main-block-all" @click.prevent="showPopup()">
      <span>全部</span>
      <img src="@/assets/images/min-icon19.png" alt="" />
    </div>
  </div>
  <van-popup v-model:show="show" round position="top" :overlay-style="overlayHeight">
    <div class="main-popup">
      <div class="popup">
        <div class="popup-content">
          <h5>全部分类</h5>
          <div class="main-block">
            <div class="main-flex-row">
              <div
                class="main-flex-cell"
                v-for="(item, i) in state.categoryDataList"
                :key="item.id"
              >
                <a
                  href="#"
                  :class="state.categoryid == item.id ? 'active' : ''"
                  @click.prevent="handleClickMenu(item.id, i)"
                >
                  <img :src="item.imgUrl" />
                  <span>{{ item.categoryName }}</span>
                </a>
              </div>
            </div>
          </div>
          <p @click="showUnPopup()"><span>点击收起</span></p>
        </div>
      </div>
    </div>
  </van-popup>

逻辑

const handleClickMenu = (id: string, index?: number) => {
    state.categoryid = id;
    chooseNav(id, index);
  };


  function chooseNav(id: string, index?: number) {
    // 当前点击元素的左边距离
    const distanceL = document
      .getElementsByClassName('flex-cell')
      [index].getBoundingClientRect().left;
    // 点击元素的一半宽度
    const elementHW = document.getElementsByClassName('flex-cell')[index].clientWidth / 2;
    // 屏幕宽度
    const screenW = document.body.clientWidth;
    // 屏幕宽度的一半
    const screenHW = document.body.clientWidth / 2;
    // 元素右边距离
    const distanceR = screenW - distanceL;
    // 获取最外层的元素
    const scrollBox = document.getElementsByClassName('flex-row');
    // 滚动条滚动的距离
    const scrollL = scrollBox[0].scrollLeft;
    // 当元素左边距离大于屏幕一半宽度  或者  右边距离大于屏幕一半距离的时候
    if (distanceL > screenHW - elementHW || distanceR > screenHW - elementHW) {
      // 滚动条最终的滚动距离
      scrollBox[0].scrollLeft = scrollL + (distanceL - screenHW + elementHW);
    }
  }

样式

<style scoped lang="less">
  .flex-row::-webkit-scrollbar {
    display: none; /* Chrome Safari */
  }
  .flex-row {
    padding-right: 0.4rem;
    display: flex;
    overflow-x: auto;
    /* 隐藏滚动条 */
    scrollbar-width: none; /* firefox */
    -ms-overflow-style: none; /* IE 10+ */
    justify-content: space-between;
    a {
      width: 100%;
      display: inline-block;
    }
    .flex-cell {
      text-align: center;
      flex-grow: 0;
      flex-shrink: 0;
      width: calc(20vw - 0.125rem);
      a.active > img {
        border-color: #40ae36;
      }
      a.active > span {
        color: #40ae36;
      }
      a > span {
        width: 100%;
        display: inline-block;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
      }
      a > img {
        margin: 0 auto;
        width: 0.8rem;
        height: 0.8rem;
        padding: 0.02rem;
        border-radius: 50rem;
        box-sizing: border-box;
        border: 0.02rem solid #fff;
      }
    }
  }
  :deep(.popup-content) {
    .main-flex-row {
      display: flex;
      flex-wrap: wrap;
      // justify-content: space-between;
      padding: 0 0.3rem;
      margin: 0.5rem 0 0.25rem 0;
      a {
        width: 100%;
        display: inline-block;
      }
      .main-flex-cell {
        text-align: center;
        width: calc(20vw - 0.125rem);
        a.active > img {
          border-color: #40ae36;
        }
        a.active > span {
          color: #40ae36;
        }
        a > span {
          width: 100%;
          display: inline-block;
          white-space: nowrap;
          overflow: hidden;
          text-overflow: ellipsis;
        }
        a > img {
          margin: 0 auto;
          width: 0.8rem;
          height: 0.8rem;
          padding: 0.02rem;
          border-radius: 50rem;
          box-sizing: border-box;
          border: 0.02rem solid #fff;
        }
      }
    }
  }
</style>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值