vue实现滑动切换效果(仅在手机模式下可用)


Posted in Javascript onJune 29, 2020

本文实例为大家分享了vue实现滑动时红黄色块左右滑动相应距离,效果如下图

vue实现滑动切换效果(仅在手机模式下可用)

实现过程主要在于实时跟踪手指滑动位置与原位置之间的偏移量,再相应移动红黄块。

红黄块布局如下

back中包含back-l,back-r左右两块,正常情况下为了隐藏其中一块,子模块需要设置display: inline-block,并且宽度都需要设置width: 100%。父模块中设置white-space: nowrap用于处理两个子模块之间的空白。

<template lang="html">
 <div class="back"
 @touchstart.prevent="touchStart"
 @touchmove.prevent="touchMove"
 @touchend="touchEnd" ref="back">
 <div class="back-l" ref="left"></div>
 <div class="back-r" ref="right"></div>
 </div>
</template>
 
<style scoped lang="stylus" rel="stylesheet/stylus">
.back
 position: fixed
 width: 100%
 height: 100px
 white-space: nowrap
 .back-l
 position: relative
 vertical-align: top
 display: inline-block
 width: 100%
 height: 100%
 background-color: red
 .back-r
 display: inline-block
 vertical-align: top
 position: relative
 width: 100%
 height: 100%
 background-color: yellow
</style>

父模块监听滑动事件

滑动事件分为三种:touchstart,touchmove,touchEnd,加上prevent避免页面相应滑动。

在touchstart中记录滑动开始点:

touchStart(e) {
  const touch = e.touches[0]
  this.touch.startX = touch.pageX
  this.touch.startY = touch.pageY
 }

touchmove中为滑动过程,手指未离开页面,离开页面时触发touchend。滑动过程中,当横向偏离位置大于纵向偏离位置时认为滑动有效,记录手指偏离位置,相应移动红黄块。

touchMove(e) {
  console.log("move");
  const touch = e.touches[0]
  //横向和纵向偏离位置
  const deltaX = touch.pageX - this.touch.startX
  const deltaY = touch.pageY - this.touch.startY
  if (Math.abs(deltaY) > Math.abs(deltaX)) {
  return
  }
  const left = this.currentPlay == 'red' ? 0 : -window.innerWidth
  var offsetWidth = Math.min(0, Math.max(-window.innerWidth,left+deltaX))
  //记录滑动的距离占屏幕宽度的百分比,如果滑动太少则不切换
  this.percent = Math.abs(offsetWidth/window.innerWidth)
  //移动红黄块  
  this.$refs.back.style["transform"] = `translate3d(${offsetWidth}px,0,0)`
  //设置动画时间  
  this.$refs.back.style["transitionDuration"] = 10
 }

计算偏移量时首先需要知道当前偏移位置,如果当前在红块,初始偏移量为0,否则初始偏移量为负的屏幕宽度。初始偏移量加上横向偏移量首先和-window.innerWidth取最大值,-window.innerWidth为最左偏移量。再和0相比较取最小值,偏移量为0或者大于零则不再(向右移动)移动,小于零则可以向左移动。

touchend中处理最终效果,如果滑动距离不大于某一值则恢复原位,否则切换。

touchEnd() {
 console.log("end");
 console.log(this.percent);
 let offsetWidth
 let percent
 //当前为红色,滑动占比大于0.1则切换,否则回到原位置
 if(this.currentPlay === 'red'){
 if(this.percent > 0.1) {
  this.currentPlay = 'yellow'
  offsetWidth = -window.innerWidth
 } else {
  offsetWidth = 0
 }
 } else {
 //当前为黄色,滑动占比大于0.9则切换,否则回到原位置
 if(this.percent < 0.9) {
  this.currentPlay = 'red'
  offsetWidth = 0
 } else {
  offsetWidth = -window.innerWidth
 }
 }
 //这里的transform是针对最开始的位置而言,而不是移动过程中的位置
 this.$refs.back.style["transform"] = `translate3d(${offsetWidth}px,0,0)`
 this.$refs.back.style["transitionDuration"] = 10
}

完整代码

<template lang="html">
 <div class="back"
 @touchstart.prevent="touchStart" @touchmove.prevent="touchMove"
 @touchend="touchEnd" ref="back">
 <div class="back-l" ref="left"></div>
 <div class="back-r" ref="right"></div>
 
 </div>
</template>
 
<script>
export default {
 data() {
 return {
  currentPlay: 'red',
  percent: 0
 }
 },
 created() {
 this.touch = {}
 },
 methods: {
 touchStart(e) {
  const touch = e.touches[0]
  this.touch.startX = touch.pageX
  this.touch.startY = touch.pageY
 },
 touchMove(e) {
  console.log("move");
  const touch = e.touches[0]
  const deltaX = touch.pageX - this.touch.startX
  const deltaY = touch.pageY - this.touch.startY
  if (Math.abs(deltaY) > Math.abs(deltaX)) {
  return
  }
  const left = this.currentPlay == 'red' ? 0 : -window.innerWidth
  var offsetWidth = Math.min(0, Math.max(-window.innerWidth,left+deltaX))
  this.percent = Math.abs(offsetWidth/window.innerWidth)
  this.$refs.back.style["transform"] = `translate3d(${offsetWidth}px,0,0)`
  this.$refs.back.style["transitionDuration"] = 10
 
 
 
 },
 touchEnd() {
  console.log("end");
  console.log(this.percent);
  let offsetWidth
  let percent
  if(this.currentPlay === 'red'){
  if(this.percent > 0.1) {
   this.currentPlay = 'yellow'
   offsetWidth = -window.innerWidth
  } else {
   offsetWidth = 0
  }
  } else {
  if(this.percent < 0.9) {
   this.currentPlay = 'red'
   offsetWidth = 0
  } else {
   offsetWidth = -window.innerWidth
  }
  }
  this.$refs.back.style["transform"] = `translate3d(${offsetWidth}px,0,0)`
  this.$refs.back.style["transitionDuration"] = 10
 }
 }
}
</script>
 
<style scoped lang="stylus" rel="stylesheet/stylus">
.back
 position: fixed
 width: 100%
 height: 100px
 white-space: nowrap
 .back-l
 position: relative
 vertical-align: top
 display: inline-block
 width: 100%
 height: 100%
 background-color: red
 .back-r
 display: inline-block
 vertical-align: top
 position: relative
 width: 100%
 height: 100%
 background-color: yellow
 
 
</style>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript面向对象之二 命名空间
Feb 08 Javascript
jQuery UI AutoComplete 使用说明
Jun 20 Javascript
关于jQuery UI 使用心得及技巧
Oct 10 Javascript
JavaScript中对象属性的添加和删除示例
May 12 Javascript
利用CSS3在Angular中实现动画
Jan 15 Javascript
基于BootStrap的图片轮播效果展示实例代码
May 23 Javascript
canvas实现弧形可拖动进度条效果
May 11 Javascript
JavaScript实现简单评论功能
Aug 17 Javascript
最简单的JS实现json转csv的方法
Jan 10 Javascript
JavaScript中的 new 命令
May 22 Javascript
微信小程序 简易计算器实现代码实例
Sep 02 Javascript
vue-cli3 热更新配置操作
Sep 18 Javascript
微信小程序设置滚动条过程详解
Jul 25 #Javascript
vuejs移动端实现div拖拽移动
Jul 25 #Javascript
vue实现拖拽的简单案例 不超出可视区域
Jul 25 #Javascript
vue实现一拉到底的滑动验证
Jul 25 #Javascript
微信小程序实现图片选择并预览功能
Jul 25 #Javascript
详细教你微信公众号正文页SVG交互开发技巧
Jul 25 #Javascript
微信小程序绘制图片发送朋友圈
Jul 25 #Javascript
You might like
咖啡豆的最常见发酵处理方法,详细了解一下
2021/03/03 冲泡冲煮
无法在发生错误时创建会话,请检查 PHP 或网站服务器日志,并正确配置 PHP 安装(win+linux)
2012/05/05 PHP
PHP解码unicode编码的中文字符代码分享
2014/08/13 PHP
php微信高级接口群发 多客服
2016/06/23 PHP
PHP基于DOMDocument解析和生成xml的方法分析
2017/07/17 PHP
PHP实现微信商户支付企业付款到零钱功能
2018/09/30 PHP
如何在centos8自定义目录安装php7.3
2019/11/28 PHP
jquery $.each 和for怎么跳出循环终止本次循环
2013/09/27 Javascript
JS替换字符串中字符即替换全部而不是第一个
2014/06/04 Javascript
浅谈JS闭包中的循环绑定处理程序
2014/11/09 Javascript
jquery实现的Accordion折叠面板效果代码
2015/09/02 Javascript
JS实现漂亮的窗口拖拽效果(可改变大小、最大化、最小化、关闭)
2015/10/10 Javascript
AngularJS向后端ASP.NET API控制器上传文件
2016/02/03 Javascript
jquery分页插件jquery.pagination.js实现无刷新分页
2016/04/01 Javascript
Javascript实现通过选择周数显示开始日和结束日的实现代码
2016/05/30 Javascript
原生JS实现匀速图片轮播动画
2016/10/18 Javascript
快速解决vue-cli不能初始化webpack模板的问题
2018/03/20 Javascript
微信小程序实现折线图的示例代码
2019/06/07 Javascript
python实现2014火车票查询代码分享
2014/01/10 Python
Python是编译运行的验证方法
2015/01/30 Python
解决python matplotlib imshow无法显示的问题
2018/05/24 Python
Python实现数据可视化看如何监控你的爬虫状态【推荐】
2018/08/10 Python
python实现简单五子棋游戏
2019/06/18 Python
解决安装python3.7.4报错Can''t connect to HTTPS URL because the SSL module is not available
2019/07/31 Python
python应用文件读取与登录注册功能
2019/09/23 Python
python小白切忌乱用表达式
2020/05/29 Python
PyTorch实现重写/改写Dataset并载入Dataloader
2020/07/14 Python
python如何导出微信公众号文章方法详解
2020/08/31 Python
Python2与Python3关于字符串编码处理的差别总结
2020/09/07 Python
python中复数的共轭复数知识点总结
2020/12/06 Python
初中生操行评语大全
2014/04/24 职场文书
小学生学习保证书
2015/02/26 职场文书
企业党建工作总结2015
2015/05/26 职场文书
2016年党支部公开承诺书
2016/03/25 职场文书
Python使用socket去实现TCP客户端和TCP服务端
2022/04/12 Python
Mybatis-plus配置分页插件返回统一结果集
2022/06/21 Java/Android