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 相关文章推荐
jQuery获取页面及个元素高度、宽度的总结——超实用
Jul 28 Javascript
javascript实现tab响应式切换特效
Jan 29 Javascript
JQuery 两种方法解决刚创建的元素遍历不到的问题
Apr 13 Javascript
JavaScript 输出显示内容(document.write、alert、innerHTML、console.log)
Dec 14 Javascript
js 判断登录界面的账号密码是否为空
Feb 08 Javascript
Bootstrap表单制作代码
Mar 17 Javascript
解决webpack打包速度慢的解决办法汇总
Jul 06 Javascript
详解ionic本地相册、拍照、裁剪、上传(单图完全版)
Oct 10 Javascript
浅谈vue项目如何打包扔向服务器
May 08 Javascript
JavaScript使用递归和循环实现阶乘的实例代码
Aug 28 Javascript
js实现整体缩放页面适配移动端
Mar 31 Javascript
基于javascript实现放大镜特效
Dec 03 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结束标签的使用细节探讨及联想
2013/03/04 PHP
PHP自动识别字符集并完成转码详解
2013/08/02 PHP
ecshop实现smtp发送邮件
2015/02/03 PHP
php查看当前Session的ID实例
2015/03/16 PHP
PHP操作mysql数据库分表的方法
2016/06/09 PHP
thinkphp5.1框架实现格式化mysql时间戳为日期的方式小结
2019/10/10 PHP
Js获取事件对象代码
2010/08/05 Javascript
通过js简单实现将一个文本内容转译成加密文本
2013/10/22 Javascript
js 一个关于图片onload加载的事
2013/11/10 Javascript
javascript读取xml实现javascript分页
2013/12/13 Javascript
innerText 使用示例
2014/01/23 Javascript
Javascript技术难点之apply,call与this之间的衔接
2015/12/04 Javascript
完美的js div拖拽实例代码
2016/09/24 Javascript
浅谈Vue.js
2017/03/02 Javascript
Bootstrap.css与layDate日期选择样式起冲突的解决办法
2017/04/07 Javascript
解决angular2在双向数据绑定时[(ngModel)]无法使用的问题
2018/09/13 Javascript
Python基于多线程操作数据库相关问题分析
2018/07/11 Python
python GUI库图形界面开发之PyQt5打开保存对话框QFileDialog详细使用方法与实例
2020/02/27 Python
解决pycharm编辑区显示yaml文件层级结构遇中文乱码问题
2020/04/27 Python
pycharm2020.2 配置使用的方法详解
2020/09/16 Python
意大利在线购买隐形眼镜网站:VisionDirect.it
2019/03/18 全球购物
中国京东和泰国中央集团合资的网站:JD CENTRAL
2020/08/22 全球购物
VLAN和VPN有什么区别?分别实现在OSI的第几层?
2014/12/23 面试题
毕业生应聘幼儿园的自荐信
2013/11/20 职场文书
个人现实表现材料
2014/02/04 职场文书
交通事故赔偿协议书范本
2014/04/15 职场文书
建筑学专业自荐书
2014/07/09 职场文书
员工趣味活动方案
2014/08/27 职场文书
事业单位个人总结
2015/02/12 职场文书
2016新年慰问信范文
2015/03/25 职场文书
走近毛泽东观后感
2015/06/04 职场文书
Go语言使用select{}阻塞main函数介绍
2021/04/25 Golang
配置nginx 重定向到系统维护页面
2021/06/08 Servers
基于Go语言构建RESTful API服务
2021/07/25 Golang
python自动化测试之Selenium详解
2022/03/13 Python
MySQL数据库简介与基本操作
2022/05/30 MySQL