手动实现基于vue构建移动触摸滑动组件——简易的swiper

       在web或移动端开发中,有时候我们需要做一个可滚动显示的banner、轮播、滑动翻页显示内容等,常用的插件就数swiper。当然如果我不想因为一个小的页面去引入一个库,那么我们就手动写一个简易版的swiper。因为正做的项目是vue中需要用到滑动翻页效果,就用vue来实现一个垂直方向滑动翻页的效果咯!
 

      核心触摸事件:touchstart、touchmove和touchend。(还有touchcancel事件,这里我们就不考虑了)

  • touchstart事件:当手指触摸屏幕时候触发,即使已经有一个手指放在屏幕上也会触发。
  • touchmove事件:当手指在屏幕上滑动的时候连续地触发。在这个事件发生期间,调用preventDefault()事件可以阻止滚动。
  • touchend事件:当手指从屏幕上离开的时候触发。

      核心动画效果: 使用CSS3的transition属性。

     一、如何实现展示页面内容:
     接下来我们要如何实现页面能向上或向下活动,我们可以把节点分为两层,第一层为页面上显示内容的视窗a,比如,这个窗口占满整个屏幕;第二层为内容容器b,容器b的大小由多页内容c组成。每页c的大小与视窗a相等,这样只要控制内容容器b的位置就可以让每一个c全部呈现在视窗a中。如下图所示(只有视窗a大小的内容是可以显示的)。

      视窗a大小等于内容c 大小,容器b是内容c的整数倍。容器b采用position: absolute,控制属性top为视窗a的整数倍,就可以控制页面显示了。再用transition: top 1s 控制过渡效果,只要给一个状态显示第几页,控制top值就可以自由滚动了。如何控制呢,接下来再看看第二部分用滑动事件来如何触发的向下/向上指令状态改变。

      我们构建DOM结构,.wiper-container为视窗a,.wiper-list为容器b,wiper-item为内容c。通过this.refs.wiperbox.offsetHeight获取a的大小,然后通过listStyle 和 itemStyle计算出合适的b、c的样式。

<div class="wiper-container" 
    ref="wiperbox"
    @touchstart="handleTouchStart"
    @touchend="handleTouchEnd"
    @touchmove="handleTouchMove">
    <div class="wiper-list" :style="listStyle">
        <div class="wiper-item" :style="itemStyle">第一页</div>
        <div class="wiper-item" :style="itemStyle">第二页</div>
        <div class="wiper-item" :style="itemStyle">第三页</div>
    </div>
</div>

      二、 如何触发滑动:

     每个触摸事件的触发都会获取到touch对象包含的属性:

  • clientX:触摸目标在视口中的x坐标。
  • clientY:触摸目标在视口中的y坐标。
  • identifier:标识触摸的唯一ID。
  • pageX:触摸目标在页面中的x坐标。
  • pageY:触摸目标在页面中的y坐标。
  • screenX:触摸目标在屏幕中的x坐标。
  • screenY:触摸目标在屏幕中的y坐标。
  • target:触目的DOM节点目标

     那么我们可以分别在touchstart 和 touchend事件中记录触摸的初始位置和结束位置,如pageY的值,两者之差我们就可以计算出手指是向上滑动还是向下滑动,这样我们就可以控制内容滑动是向上翻页还是向下翻页,我们也可以设置一个阈值才出发滑动翻页,避免小幅度触摸导致的翻页。


handleTouchStart: function(e){
    this.startPoint = e.touches[0].pageY;
}

handleTouchEnd: function(e){
    let end = e.changedTouches[0].pageY;
    let start = this.startPoint;
    let delta = start - end;
    let goDown = 0;
    if(delta > 10){
        goDown = 1;
    }else if(delta < -10){
        goDown = -1;
    }
    this.changeItem(goDown);
}

      三、提升效果

      实现前面两部分内容,向下滑动,页面就向下滑动,向上滑动,页面就向上滑动。但是,如果手指不松开,页面不会跟随手指滑动,而是等手指松开后才滑动。这时我们需要前面未用到的touchmove事件来实现手指跟随效果。手指不断滑动tochmove就会不断触发,我们还是获取pageX值,计算tochmove的值与tochstart记录的初始值进行比较,并在容器b的当前位置上实时修改top值,同时禁用过渡效果,跟随效果就可以实现了。

handleTouchMove: function(e){
    let poChange = e.changedTouches[0].pageY - this.startPoint;
    this.pointChange = poChange
}

四、以此类推

       以上原理可以实现手动触发上下滑动效果,稍加修改可以扩展更多:

  • 如果我们将height切换为width,top切换为left,那么我们也就可以实现左右滑动的效果。
  • 如果我们再设置定时器控制页面的切换,那么我们就可以实现轮播图跑马灯banner。
  • 如果我们抽象成组件,再通过传入参数控制组件就可以拓展以上的如果,构造为可复用的组件了。

五、抽象公共组件

      到第三部分已经可以满足初步的建议swiper效果的需求,有多个地方使用这样的页面,我们可继续抽象出公共组件,页面可以直接使用。

// 页面中引入滑动组件
<template>
    <div class="hello">
        <wiper>
            <wiperitem color="#90F7EC">
                <div>第一页</div>
            </wiperitem>
            <wiperitem color="#7CAAFF">
                <span>第二页</span>
            </wiperitem>
            <wiperitem>
                <span>第三页</span>
            </wiperitem>
        </wiper>
    </div>
</template>

     我把视窗和内容容器都定义在wiper组件中,wiperitem接收每个内容页的内容,两个组件中用到了vue中的插槽slot,wiper组件中可以根据 this.$slots.default 计算出通过slot传入的组件个数来计算有多少页、并控制容器大小,在wiper中处理页面触摸事件和动画效果;在wiperitem中获取wiper对slot传入的参数计算每个页面大小。

// weiper组件  视窗a + 容器b
<template>
    <div class="wiper-container" 
        ref="wiperbox"
        @touchstart="handleTouchStart"
        @touchend="handleTouchEnd"
        @touchmove="handleTouchMove"
    >
        <div class="wiper-list" :style="listStyle" >
            <slot :itemHeight="itemHeight"></slot>
        </div>
    </div>
</template>
//wiperitem组件  内容c
<template>
    <div class="wiper-item" :style="itemStyle">
        <slot></slot>
    </div>
</template>

具体slot的使用可以参照vue官方文档:https://cn.vuejs.org/v2/guide/components-slots.html
完整代码见:https://github.com/chenjycm/myswiper

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
vue-awesome-swiper是一个基于Vue.js的插件,用于实现H5滑动翻页效果。它是在swiper的基础上进行了封装,使得在Vue项目中使用swiper变得更加方便和灵活。 要在vue中使用vue-awesome-swiper,首先需要在main.js中引入VueAwesomeSwiper插件,并导入swiper的样式文件。具体的代码如下: import VueAwesomeSwiper from 'vue-awesome-swiper' import 'swiper/dist/css/swiper.css' Vue.use(VueAwesomeSwiper) 这样就可以在Vue组件中使用vue-awesome-swiper实现H5滑动翻页效果了。你可以在需要使用swiper组件中引入并注册vue-awesome-swiper组件,然后使用组件的方式来配置和控制swiper的各种参数和功能。通过配置不同的选项,你可以实现各种不同的滑动翻页效果,满足你的需求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [vue案例 - vue-awesome-swiper实现h5滑动翻页效果](https://blog.csdn.net/weixin_33881050/article/details/93267999)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [vue移动端使用swiper+vue-awesome-swiper实现滑动选择](https://blog.csdn.net/weixin_45842078/article/details/119141775)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值