JS 使用swiper完成tab滑动换页功能

Posted 码小余の博客

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS 使用swiper完成tab滑动换页功能相关的知识,希望对你有一定的参考价值。

纯原生JS实现的tab滑动换页功能

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <meta
      name="viewport"
      content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"
    />
    <title>景区榜单</title>
    <link rel="stylesheet" href="../css/style.css" />
    <link rel="stylesheet" href="../css/swiper-bundle.min.css" />
  </head>

  <body>
    <div class="bg h-full" id="main">
      <div class="pt-10 h-full">
        <div class="flex justify-between align-center mt-10" id="tab">
          <div
            class="bg-fff p-10 fs-13 rounded-t-5 font-bold color-red transition-all-300"
            onclick="onTab(0)"
          >
            热搜榜
          </div>
          <div
            class="bg-fff p-10 fs-13 rounded-t-5 transition-all-300"
            onclick="onTab(1)"
          >
            最佳人气榜
          </div>
          <div
            class="bg-fff p-10 fs-13 rounded-t-5 transition-all-300"
            onclick="onTab(2)"
          >
            最受欢迎榜
          </div>
          <div
            class="bg-fff p-10 fs-13 rounded-t-5 transition-all-300"
            onclick="onTab(3)"
          >
            收藏榜
          </div>
          <div
            class="bg-fff p-10 fs-13 rounded-t-5 transition-all-300"
            onclick="onTab(4)"
          >
            点赞榜
          </div>
        </div>

        <!-- 指示条 start -->
        <div
          class="left-0 bottom-0 h-3 w-59 bg-red translate-x-0"
          id="active_bar"
        ></div>
        <!-- 指示条 end -->

        <div class="swiper h-full">
          <div class="swiper-wrapper">
            <div class="swiper-slide" id="hot">
              <div class="font-bold text-center mt-10 fs-28">ONE</div>
            </div>

            <div class="swiper-slide" id="popularity">
              <div class="font-bold text-center mt-10 fs-28">TWO</div>
            </div>

            <div class="swiper-slide" id="welcome">
              <div class="font-bold text-center mt-10 fs-28">THREE</div>
            </div>

            <div class="swiper-slide" id="collect">
              <div class="font-bold text-center mt-10 fs-28">FOUR</div>
            </div>

            <div class="swiper-slide" id="like">
              <div class="font-bold text-center mt-10 fs-28">FIVE</div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </body>
  <script src="../js/swiper-bundle.min.js"></script>
  <script type="text/javascript">
    var tabEl = document.getElementById('tab')
    var activeBarEl = document.getElementById('active_bar')
    var startX = 0
    var currentTranslateX = 0
    var currentTabWidth = 0
    var swiperInnerLen = 0 // 轮播图总宽度
    var slidechange = false // slide是否改变
    var transitionTimer = 0 // 动画计时器

    // 配置选项
    var activeBarConfig = 
      disableEdgePull: false // 禁用 active_bar 边缘左右拉动
    

    var mySwiper = new Swiper('.swiper', 
      resistanceRatio: 0,
      on: 
        touchStart: function (swiper, event) 
          // 移除过渡动画
          activeBarEl.classList.remove('transition-all-300')
          // 清除计时器
          clearTimeout(transitionTimer)

          slidechange = false
          startX = event.touches[0].pageX

          var x = parseFloat(
            window.getComputedStyle(activeBarEl).transform.split(',')[4]
          )
          var tabLeft = tabEl.children[mySwiper.activeIndex].offsetLeft

          // console.log(x, tabLeft)
          // 如果当前 translateX 值没有在 tab 的边缘上,则不用重新赋值(防止出现active_bar错位问题)
          if (x == tabLeft) 
            currentTranslateX = x
          

          // 当前tab栏的宽度
          currentTabWidth = tabEl.children[mySwiper.activeIndex].clientWidth

          // 轮播图内层长度
          swiperInnerLen = 0
          Array.from(mySwiper.slides).forEach((item) => 
            swiperInnerLen += item.swiperSlideSize
          )
        ,
        touchMove: function (swiper, event) 
          // 移除过渡动画
          activeBarEl.classList.remove('transition-all-300')
          // 清除计时器
          clearTimeout(transitionTimer)

          var moveX = event.touches[0].pageX
          // console.log(moveX)

          // 滑动距离
          var distance = Math.abs(startX - moveX)

          // 屏幕宽度
          var screenWidth = window.screen.width

          // 计算 active_bar 需要移动的距离
          var activeBarMoveX = (distance / swiperInnerLen) * screenWidth

          // 获取当前 active_bar 的宽度
          var currentActiveBarWidth = activeBarEl.clientWidth

          if (swiper.swipeDirection == 'next') 
            // 左滑

            // 获取下一个 tab 元素
            var nextTabEl = tabEl.children[mySwiper.activeIndex + 1]
            // 获取当前 tab 元素
            var currentTabEl = tabEl.children[mySwiper.activeIndex]
            if (nextTabEl) 
              // 如果下一个 tab 元素存在,则获取它的宽度
              var nextTabWidth = nextTabEl.clientWidth
              var currentTabWidth = currentTabEl.clientWidth
              // 当前 tab 和 下一个 tab 宽度之差
              var diffVal = nextTabWidth - currentTabWidth

              // 改变当前 active_bar 的宽度
              activeBarEl.style.width = `$
                currentActiveBarWidth + (diffVal / screenWidth) * distance
              px`
            

            if (activeBarConfig.disableEdgePull) 
              // 获取最后一个tab栏的 translateX 值
              var lastTabTransX =
                screenWidth -
                tabEl.children[tabEl.children.length - 1].clientWidth

              activeBarEl.style.transform = `translateX($
                currentTranslateX + activeBarMoveX >= lastTabTransX
                  ? lastTabTransX
                  : currentTranslateX + activeBarMoveX
              )`
             else 
              activeBarEl.style.transform = `translateX($
                currentTranslateX + activeBarMoveX
              px)`
            
           else if (swiper.swipeDirection == 'prev') 
            // 右滑

            // 获取上一个 tab 元素
            var prevTabEl = tabEl.children[mySwiper.activeIndex - 1]
            // 获取当前 tab 元素
            var currentTabEl = tabEl.children[mySwiper.activeIndex]
            if (prevTabEl) 
              // 如果下一个 tab 元素存在,则获取它的宽度
              var prevTabWidth = prevTabEl.clientWidth
              var currentTabWidth = currentTabEl.clientWidth
              // 差
              diffVal = prevTabWidth - currentTabWidth

              // 改变当前 active_bar 的宽度
              activeBarEl.style.width = `$
                currentActiveBarWidth + (diffVal / screenWidth) * distance
              px`
            

            if (activeBarConfig.disableEdgePull) 
              activeBarEl.style.transform = `translateX($
                currentTranslateX - activeBarMoveX <= 0
                  ? 0
                  : currentTranslateX - activeBarMoveX
              px)`
             else 
              activeBarEl.style.transform = `translateX($
                currentTranslateX - activeBarMoveX
              px)`
            
          
        ,
        slideChange: function () 
          slidechange = true
        ,
        touchEnd: function (swiper, event) 
          // 添加过渡动画
          activeBarEl.classList.add('transition-all-300')
          clearTimeout(transitionTimer)
          transitionTimer = setTimeout(() => 
            activeBarEl.classList.remove('transition-all-300')
            clearTimeout(transitionTimer)
          , 300)

          // 使用setTimeout,保证了touchEnd事件在slideChange事件之后执行
          setTimeout(() => 
            var newTabEl = tabEl.children[mySwiper.activeIndex]
            activeBarEl.style.transform = `translateX($newTabEl.offsetLeftpx)`
            activeBarEl.style.width = `$newTabEl.clientWidthpx`
            if (slidechange) 
              Array.from(tabEl.children).forEach((item) => 
                item.classList.remove('font-bold')
                item.classList.remove('color-red')
              )
              newTabEl.classList.add('font-bold')
              newTabEl.classList.add('color-red')
            
          )
        
      
    )

    // tab点击事件
    function onTab(index) 
      mySwiper.slideTo(index)

      // 移除过渡动画
      activeBarEl.classList.remove('transition-all-300')
      // 清除计时器
      clearTimeout(transitionTimer)

      // 添加过渡动画
      activeBarEl.classList.add('transition-all-300')

      transitionTimer = setTimeout(() => 
        activeBarEl.classList.remove('transition-all-300')
        clearTimeout(transitionTimer)
      , 300)

      var newTabEl = tabEl.children[index]
      activeBarEl.style.transform = `translateX($newTabEl.offsetLeftpx)`
      activeBarEl.style.width = `$newTabEl.clientWidthpx`

      Array.from(tabEl.children).forEach((item) => 
        item.classList.remove('font-bold')
        item.classList.remove('color-red')
      )
      newTabEl.classList.add('font-bold')
      newTabEl.classList.add('color-red')
    
  </script>
</html>

功能

  • 左右滑动换页
  • 点击换页
  • 底部activeBar跟随滑动
  • 底部activeBar长度跟随变化
  • 其他需要的功能可以在此基础上自己开发

效果如下

以上是关于JS 使用swiper完成tab滑动换页功能的主要内容,如果未能解决你的问题,请参考以下文章

JS 使用swiper完成tab滑动换页功能

移动端tab滑动和上下拉刷新加载

swiper.js滑动插件

swipe.js怎么动态添加滑动元素

swipe.js如何动态添加滑动元素?

Swiper的基本使用