zoukankan      html  css  js  c++  java
  • 类似vant中的tab实现

    在使用 vant weapp 开发微信小程序过程中tab组件无法满足现需求,不能在tab项中添加图片;于是自己动手写了一个tab组件,并实现点击后将选中的tab移动到视线中央;

    html

    <div class="nav_left" ref="nav_left">
      <div class="nav_group" ref="nav_group">
        <div
                class="nav_btn"
                ref="nav_btn"
                v-for="(item, index) in navList"
                :key="item.id"
                :class="item.id === activeSpotType ? 'map_top_active' : ''"
                @click="navClick(index)"
                >
          <img
               class="icon"
               v-if="item.id === activeSpotType"
               :src="item.iconSrc"
               />
          <img class="icon" v-else :src="item.iconSrc" />
          {{ item.name }}
        </div>
      </div>
    </div>

    css (css使用的是scss预编译),

    .nav_left {
      display: inline-block;
      vertical-align: top;
       calc(100% - 35px);
      height: 100%;
      .nav_group {
         100%;
        height: 100%;
        white-space: nowrap;
        display: flex;
        overflow-x: scroll;
        scroll-behavior: smooth; // 滚动行为 平稳
        &::-webkit-scrollbar {
          display: none;
        }
      }
      .nav_btn {
        margin-top: 7px;
        padding: 6px 20px;
        display: inline-block;
        font-size: 14px;
        border: none;
        height: 32px;
        line-height: 17px;
        background: #FFF;
        box-sizing: border-box;
        outline: none;
        border-radius: 18px;
        .icon{
           16px;
          height: 17px;
          margin-right: 2px;
          vertical-align: bottom;
        }
      }
      .map_top_active {
        color: #FFF;
        background: rgba(81, 166, 255, 1);
        transition: all ease 0.3s;
      }
    }

    js

    export default {
      data(){
          activeSpotType: '12301',
          navList: [
           {
              id: '12301',
              name: '女装',
              selectedIcon: '选中时的图标链接',
              unselectedIcon: '未选中时的图标链接',
            },
           {
              id: '12302',
              name: '男装',
              selectedIcon: '选中时的图标链接',
              unselectedIcon: '未选中时的图标链接',
            },
           {
              id: '12303',
              name: '数码',
              selectedIcon: '选中时的图标链接',
              unselectedIcon: '未选中时的图标链接',
            },
           {
              id: '12304',
              name: '家电',
              selectedIcon: '选中时的图标链接',
              unselectedIcon: '未选中时的图标链接',
            },
           {
              id: '12305',
              name: '生鲜',
              selectedIcon: '选中时的图标链接',
              unselectedIcon: '未选中时的图标链接',
            }
          ]  
      },
      methods {
        // tab点击事件
        navClick(index) {
          this.activeSpotType = this.navList[index].id;
          this.handleScroll(index)
        },
    
        // 选中tab时滚动居中
        handleScroll(index) {
          let boxHalf = this.$refs.nemu.offsetWidth / 2;
          // 单个item的宽度
          let itemLeft = this.$refs.nav_btn[index].offsetLeft;
          // 选中状态的item宽度
          let itemWidth = this.$refs.nav_btn[index].offsetWidth;
          
          // 使用js添加滚动过渡动画
          let scrollLeft = 0;
          if (boxHalf <= itemLeft) {
            // 设置滚动距离实现当前选中item居中显示
            // 添加 css: overflow-x: scroll; scroll-behavior: smooth; // 设置之后滚动更丝滑
            // this.$refs.nav_group.scrollLeft = (itemLeft - boxHalf) + itemWidth / 2
            scrollLeft =  (itemLeft - boxHalf) + itemWidth / 2
          }else {
            // this.$refs.nav_group.scrollLeft = 0
            scrollLeft = 0;
          }
          this.scrollSmoothTo(this,scrollLeft)
          
          // 使用css添加滚动过渡动画
          if (boxHalf <= itemLeft) {
            // 设置滚动距离实现当前选中item居中显示
            // 在 overflow-x: scroll;的元素中添加css: scroll-behavior: smooth;
            this.$refs.nav_group.scrollLeft = (itemLeft - boxHalf) + itemWidth / 2
          }else {
            this.$refs.nav_group.scrollLeft = 0
          }
        },
    
        // 居中时添加过渡动画; scroll-behavior 的兼容性很差,移动端基本不能用使用,所以还得使用js来实现过渡效果 
        scrollSmoothTo (_this,position) {
          if (!window.requestAnimationFrame) {
            window.requestAnimationFrame = function(callback, element) {
              return setTimeout(callback, 17);
            };
          }
          // 当前滚动高度
          let currentLeft = _this.$refs.nav_group.scrollLeft;
          // 滚动step方法
          var step = function () {
            // 距离目标滚动距离
            var distance = position - currentLeft;
            // 目标滚动位置
            currentLeft = currentLeft + distance / 5;
            if (Math.abs(distance) < 1) {
              _this.$refs.nav_group.scrollLeft = position
            } else {
              _this.$refs.nav_group.scrollLeft = currentLeft
              requestAnimationFrame(step);
            }
          };
          step();
        },
      }
    }

    实例图:

     scroll-behavior 兼容性不太友好,如果是在PC端使用不考虑兼容性的话还是很不错的(scroll-behavior: smooth; 一行代码解决所有问题)

    虚心求教
  • 相关阅读:
    Python学习笔记(尚硅谷)——变量
    四级高频词-工作类
    转载--JS根据浏览器的useAgent来判断浏览器的类型
    MySQL上传文件容量过大com.mysql.jdbc.PacketTooBigException
    关于<input type="file" >浏览器兼容问题
    IDictionary与TryGetValue
    生成自增ID列
    利用C#将PCM格式的Wav进行对文件裁剪截取、淡入淡出、保存为音频文件相关详细代码解释
    DevExpress控件学习总结
    C# 音频操作系统项目总结
  • 原文地址:https://www.cnblogs.com/yangchin9/p/15565917.html
Copyright © 2011-2022 走看看