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 相关文章推荐
提交表单时执行func方法实现代码
Mar 17 Javascript
javascript重写alert方法的实例代码
Mar 29 Javascript
javascript右下角弹层及自动隐藏(自己编写)
Nov 20 Javascript
JavaScript中String.match()方法的使用详解
Jun 06 Javascript
jQuery实现鼠标滑向当前图片高亮显示并且其它图片变灰的方法
Jul 27 Javascript
JavaScript数组对象实现增加一个返回随机元素的方法
Jul 27 Javascript
js密码强度检测
Jan 07 Javascript
使用JQuery中的trim()方法去掉前后空格
Sep 16 Javascript
全面解析vue中的数据双向绑定
May 10 Javascript
BootstrapTable加载按钮功能实例代码详解
Sep 22 Javascript
JavaScript显式数据类型转换详解
Mar 18 Javascript
webpack 代码分离优化快速指北
May 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
PHP sprintf() 函数的应用(定义和用法)
2012/06/29 PHP
php中如何防止表单的重复提交
2013/08/02 PHP
通过PHP设置BugFree获取邮箱通知
2019/04/25 PHP
用倒置滤镜把div倒置,再把table倒置。
2007/07/31 Javascript
JavaScript 版本自动生成文章摘要
2008/07/23 Javascript
基于node.js的快速开发透明代理
2010/12/25 Javascript
基于JQUERY的多级联动代码
2012/01/24 Javascript
JavaScript 对任意元素,自定义右键菜单的实现方法
2013/05/08 Javascript
JS 有趣的eval优化输入验证实例代码
2013/09/22 Javascript
JS对img标签进行优化使用onerror显示默认图像
2014/04/24 Javascript
jQuery选择器源码解读(三):tokenize方法
2015/03/31 Javascript
jquery实现初次打开有动画效果的网页TAB切换代码
2015/09/06 Javascript
jQuery实现的经典竖向伸缩菜单效果代码
2015/09/24 Javascript
使用jQuery制作基础的Web图片轮播效果
2016/04/22 Javascript
几行js代码实现自适应
2017/02/24 Javascript
vue组件数据传递、父子组件数据获取,slot,router路由功能示例
2019/03/19 Javascript
axios异步提交表单数据的几种方法
2019/08/11 Javascript
微信小程序实现通讯录列表展开收起
2020/11/18 Javascript
Python中的sort()方法使用基础教程
2017/01/08 Python
Python实现的rsa加密算法详解
2018/01/24 Python
对django后台admin下拉框进行过滤的实例
2019/07/26 Python
django将网络中的图片,保存成model中的ImageField的实例
2019/08/07 Python
Django values()和value_list()的使用
2020/03/31 Python
HTML5中使用postMessage实现两个网页间传递数据
2016/06/22 HTML / CSS
全球性的在线购物网站:Zapals
2017/03/22 全球购物
FC-Moto美国:欧洲最大的摩托车服装和头盔商店之一
2019/08/24 全球购物
抽象类和接口的区别
2012/09/19 面试题
国际商务专业职业生涯规划书范文
2014/01/17 职场文书
给护士表扬信
2014/01/19 职场文书
学生会干部自荐信
2014/02/04 职场文书
大学新生军训自我鉴定范文
2014/09/13 职场文书
遗嘱继承权公证书
2015/01/26 职场文书
新课程改革心得体会
2016/01/22 职场文书
Python使用scapy模块发包收包
2021/05/07 Python
使用Python脚本对GiteePages进行一键部署的使用说明
2021/05/27 Python
python超详细实现完整学生成绩管理系统
2022/03/17 Python