移动端左右滑动切换页面效果完整代码(纯JavaScript)

 更新时间:2025年03月26日 09:01:33   作者:七条小鲤鱼LY  
这篇文章主要介绍了如何通过原生JavaScript实现移动端左右滑动效果,并结合tab切换卡功能,文中通过代码介绍的非常详细,需要的朋友可以参考下

一.介绍左右滑动的重要性

移动端左右滑动效果是一种常见的用户界面交互方式,它能够提供流畅的用户体验并增强应用的直观性。以下是一些实现移动端左右滑动效果的场景和方法:

  • 页面切换:在移动端应用中,左右滑动可以用来在不同的页面或视图之间切换。这种效果可以用于图像画廊、故事讲述或导航菜单等场景。

  • 列表滑动:在长列表中,用户可以通过左右滑动来浏览不同的列表项。这种滑动效果可以提高用户在浏览大量数据时的效率。

  • 卡片式布局:在卡片式布局中,左右滑动可以帮助用户在不同的卡片之间切换,每个卡片代表一个独立的信息块或功能模块。

  • 弹出菜单:移动端的弹出菜单或侧边栏可以通过左右滑动来显示或隐藏,为用户提供更多的操作选项或信息。

  • 过渡动画:在Vue中,可以使用transition组件来实现左右滑动的过渡动画。例如,可以通过监听触摸事件来捕捉用户的滑动动作,并使用CSS过渡动画来实现平滑的页面切换效果。

  • 滑动库:如果需要快速实现滑动效果,并且不需要过多的定制化,可以考虑使用第三方滑动库,如Swiper、Hammer.js等。这些库提供了丰富的API和更稳定的体验。

  • 自定义滑动动画:开发者可以根据具体需求,使用CSS和JavaScript来实现自定义的滑动动画效果。这包括定义动画样式、监听触摸事件以及处理滑动逻辑。

  • 性能优化:在实际项目中,还需要考虑性能优化,如使用keep-alive来缓存页面,减少页面的重复渲染,以及使用防抖或节流技术来避免频繁触发事件。

通过这些方法,开发者可以在移动端应用中实现左右滑动效果,提升用户的交互体验。

二、实现的思路

第一步:事件监听

在移动端实现滑动效果,需要监听三个关键的触摸事件:

  • touchStart:当用户开始触摸屏幕时触发。
  • touchMove:当用户在屏幕上移动手指时触发。
  • touchEnd:当用户抬起手指,结束触摸操作时触发。

第二步:事件处理逻辑

接下来,我们需要明确在每个事件触发时应该执行的操作:

  • touchStart 事件:

    • 记录触摸开始时的坐标(startX)。
    • 初始化滑动距离(distanceX)为0。
    • 重置滑动容器的初始位置。
    • 设置一个标志(isMove)来跟踪是否开始滑动。
    • 代码:
              //按下
              function handleTouchStart(e) {
                  startX = e.touches[0].clientX;
                  console.log(startX); //当前按下的位置
              }
  • touchMove 事件:

    • 获取当前触摸点的坐标(currentX)。
    • 计算滑动距离(distanceX)为当前坐标与起始坐标的差值。
    • 根据滑动距离更新滑动容器的位置。
    • 判断滑动方向,如果超出边界则限制滑动范围。
    • 如果滑动距离超过一定阈值,可以设置一个标志来触发页面切换。
    • 代码:
       //按下移动
              function handleTouchMove(e) {
                  const moveX = e.touches[0].clientX;
                  // console.log(moveX);
                  const movedDistance = Math.abs(moveX - startX); // 计算移动的距离
                  console.log(movedDistance);
                  
                  // 如果移动的距离小于80,不进行更新位置的操作
                  if (movedDistance < 80) {
                      return;
                  }
      
                  //如果 moveX 大于 startX 就是往右滑动 并且页数为0 就不行 ,或者 moveX 小于 startX 并且页数是最后一页页不行
                  if ((moveX > startX && pageIndex === 0) ||
                      (moveX < startX && pageIndex === oSliderItems.length - 1)) {
                      return
                  }
                  distanceX = moveX - startX;
                  setTranslateX(-pageWith * pageIndex + distanceX)
                  isMove = true;
              }
  • touchEnd 事件:

    • 判断滑动距离是否超过页面切换的阈值。
    • 如果超过阈值,执行页面切换逻辑。
    • 如果未超过阈值,执行回弹逻辑,将滑动容器恢复到初始位置。
    • 重置滑动相关的变量,为下一次滑动做准备。
    • //松开
              function handleTouchEnd() {
                  if (isMove) {
                      if (Math.abs(distanceX) >= pageWith / 3) {
                          if (distanceX > 0) {
                              pageIndex--;
                          }
                          if (distanceX < 0) {
                              pageIndex++;
                          }
                      }
                      setTranslateX(- pageIndex * pageWith)
                  }
      
                  startX = 0;
                  distanceX = 0;
                  isMove = false
              }
      
              function setTranslateX(tranX) {
                  oScrollWrapper.style.transition = 'all .1s'
                  oScrollWrapper.style.transform = `translate(${tranX}px)`
              }

注意:在touchMove 事件,中需要判断一下,往右或者往左滑动的距离是否大于50-80,这样可以避免如果页面是一个很长的page,往下滚动就会左右抖动,影响用户体验。

-----全部代码-以及效果展示 (JavaScript)

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

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>demo</title>
    <script>
        document.documentElement.style.fontSize =
            document.documentElement.clientWidth / 37.5 + 'px'
    </script>
    <style>
        body {
            margin: 0;
        }

        html,
        body,
        #app {
            height: 100%;
        }

        div {
            display: flex;
            width: 100%;
            flex-direction: column;
        }

        .slider-page {
            position: relative;
            height: 100%;
            overflow: hidden;
        }

        .scroll-wrapper {
            position: absolute;
            width: 400vw;
            height: 100%;
            flex-direction: row;
        }

        .slider-item {
            width: 100vw;
            height: 100%;
            flex: 1;
        }

        .slider-item:nth-child(1) {
            background-color: rgb(247, 150, 150);
        }

        .slider-item:nth-child(2) {
            background-color: rgb(123, 255, 0);
        }

        .slider-item:nth-child(3) {
            background-color: rgb(0, 255, 238);
        }

        .slider-item:nth-child(4) {
            background-color: rgb(255, 0, 195);
        }

        .slider-item .inner {
            height: 100%;
            justify-content: center;
            align-items: center;
            font-size: 50px;
        }
    </style>
</head>

<body>
    <div id="app">
        <div class="slider-page">
            <div class="scroll-wrapper">
                <div class="slider-item">
                    <div class="inner">Page1</div>
                </div>
                <div class="slider-item">
                    <div class="inner">Page2</div>
                </div>
                <div class="slider-item">
                    <div class="inner">Page3</div>
                </div>
                <div class="slider-item">
                    <div class="inner">Page4</div>
                </div>
            </div>
        </div>
    </div>

    <script>
        //oSlidePage 最大的页面盒子
        //oScrollWrapper内部的盒子总宽
        // oSliderItems 每个小盒子
        // pageWith 页面宽度
        const oSlidePage = document.querySelector('.slider-page'),
            oScrollWrapper = oSlidePage.querySelector('.scroll-wrapper'),
            oSliderItems = oScrollWrapper.querySelectorAll('.slider-item'),
            pageWith = oSlidePage.offsetWidth;
        console.log('当前视口的宽度', pageWith);

        // 移动端事件  touchstart  touchmove touchend
        let startX = 0,
            pageIndex = 0,
            distanceX = 0
        isMove = false;

        //初始化
        const init = () => {
            bindEvent()
        }

        function bindEvent() {
            oScrollWrapper.addEventListener('touchstart', handleTouchStart, false)
            oScrollWrapper.addEventListener('touchmove', handleTouchMove, false)
            oScrollWrapper.addEventListener('touchend', handleTouchEnd, false)
        }
        //按下
        function handleTouchStart(e) {
            startX = e.touches[0].clientX;
            console.log(startX);

        }
        //按下移动
        function handleTouchMove(e) {
            const moveX = e.touches[0].clientX;
            // console.log(moveX);
            const movedDistance = Math.abs(moveX - startX); // 计算移动的距离
            console.log(movedDistance);
            
            // 如果移动的距离小于80,不进行更新位置的操作
            if (movedDistance < 80) {
                return;
            }

            //如果 moveX 大于 startX 就是往右滑动 并且页数为0 就不行 ,或者 moveX 小于 startX 并且页数是最后一页页不行
            if ((moveX > startX && pageIndex === 0) ||
                (moveX < startX && pageIndex === oSliderItems.length - 1)) {
                return
            }
            distanceX = moveX - startX;
            setTranslateX(-pageWith * pageIndex + distanceX)
            isMove = true;
        }
        //松开
        function handleTouchEnd() {
            if (isMove) {
                if (Math.abs(distanceX) >= pageWith / 3) {
                    if (distanceX > 0) {
                        pageIndex--;
                    }
                    if (distanceX < 0) {
                        pageIndex++;
                    }
                }
                setTranslateX(- pageIndex * pageWith)
            }

            startX = 0;
            distanceX = 0;
            isMove = false
        }

        function setTranslateX(tranX) {
            oScrollWrapper.style.transition = 'all .1s'
            oScrollWrapper.style.transform = `translate(${tranX}px)`
        }

        init()
    </script>
</body>

</html>

扩展:实现滑动效果并结合tab切换卡,实现思路如下:

1. 设计布局

首先,设计你的tab切换卡的布局。这通常包括一个顶部的tab栏和下方的内容区域。每个tab对应内容区域中的一个页面。

2. 使用变量控制高亮

使用一个变量(如pageIndex)来跟踪当前激活的tab。这个变量将用于控制tab栏中哪个tab是高亮显示的。

3. 实现滑动逻辑

在滑动逻辑中,除了更新滑动容器的位置外,还需要根据滑动的距离来更新pageIndex。当用户滑动到新页面时,相应的tab应该被高亮。

4. 监听滑动事件

touchMovetouchEnd事件中,根据滑动的距离来更新pageIndex,并相应地更新tab栏的高亮状态。

总结

到此这篇关于移动端左右滑动切换页面效果的文章就介绍到这了,更多相关js移动端左右滑动切换内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 发两个小东西,ASP/PHP 学习工具。 用JavaScript写的

    发两个小东西,ASP/PHP 学习工具。 用JavaScript写的

    发两个小东西,ASP/PHP 学习工具。 用JavaScript写的...
    2007-04-04
  • 用javascript实现放大镜效果

    用javascript实现放大镜效果

    这篇文章主要为大家详细介绍了用javascript实现放大镜效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • js实现按钮颜色渐变动画效果

    js实现按钮颜色渐变动画效果

    这篇文章主要介绍了js实现按钮颜色渐变动画效果的方法,涉及javascript鼠标事件及页面表单元素样式的动态操作技巧,需要的朋友可以参考下
    2015-08-08
  • 原生JS实现幻灯片

    原生JS实现幻灯片

    本文主要介绍了原生JS实现幻灯片的示例代码,具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • Web3.js查询以太币和代币余额及转账

    Web3.js查询以太币和代币余额及转账

    这篇文章主要介绍了Web3.js查询以太币和代币余额以及转账,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • 你有必要知道的25个JavaScript面试题

    你有必要知道的25个JavaScript面试题

    这篇文章主要为大家分享了我们有必要知道的25个JavaScript面试题。想要顺利通过面试的朋友可以参考一下
    2015-12-12
  • 详解ECMAScript typeof用法

    详解ECMAScript typeof用法

    typeof 返回变量的类型字符串值 、其中包括 “object”、“number”、“string”、“undefined”、“boolean”。这篇文章重点给大家介绍ECMAScript typeof用法,需要的朋友参考下
    2018-07-07
  • JavaScript原始数据类型Symbol的用法详解

    JavaScript原始数据类型Symbol的用法详解

    Symbol是ES6中引入的一种新的基本数据类型,用于表示一个独一无二的值。它是JavaScript中的第七种数据类型。本文将详细讲讲Symbol的使用,需要的可以参考一下
    2022-11-11
  • layui select 禁止点击的实现方法

    layui select 禁止点击的实现方法

    今天小编就为大家分享一篇layui select 禁止点击的实现方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-09-09
  • js+html+css实现手动轮播和自动轮播

    js+html+css实现手动轮播和自动轮播

    这篇文章主要为大家详细介绍了js+html+css实现手动轮播和自动轮播效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12

最新评论