本人在作一个简易项目时,须要实现以下效果:菜单宽度超过屏宽,靠手指左右滑动显示完成内容(菜单自己仍是二级菜单)数组
很显然须要用到touchstart/touchmove/touchend事件。浏览器
但本人对touch事件无甚了解,也所以频频碰壁,折腾许久才实现这一效果。ide
现将相关关键点记录以下。动画
一、获取touch事件的手指位置this
本人最初使用【e.pageX】,但只有苹果平台支持。后来得知须要使用【e.touches[0].pageX】spa
e.touches这一数组存储了当前每根手指的位置。code
二、二级菜单屡次刷新blog
应事先效果是:绑定click事件。点击下拉,再点击上滑。事件
可能触屏过于敏感,致使屡次触发click事件。get
解决方式为:
[1]、为动画中的div添加【isAnimate】属性(动画结束后设为false),若为true则直接return
[2]、若二级菜单高度大于0,则不进行下拉操做,直接return
三、为滑动添加缓停效果后经常失灵
缓停效果模仿触屏平台浏览器的滑动效果,根据手指移动速度,在手指触摸结束后还有一段缓冲。
经过记录两次touchmove事件的坐标,和时间,dx/dt便可求得横向速度。
缓停的实现以下:
一、速度 X 摩擦系数
二、当前位置 + 速度
三、边界判断
速度<1时中止动画。每次触摸开始清定时器。
var curX = 0; var curT = 0; var speedX = 0; var friction = 0.9; function toEnd(){ if( Math.abs(speedX) < 1 ){ return; } var tbc = true; speedX *= friction; self.thisX += speedX; if(self.thisX > 0) { self.thisX = 0; tbc = false;} else if(self.thisX < dw) { self.thisX = dw; tbc = false; } self.style.marginLeft = self.thisX + 'px'; if(tbc) { self.timer = setTimeout(toEnd, 33); } }
但本人屡次实验发现,在必定条件下两次touchmove求得的间隔为0,即缓停效果消失。
故而本人在计算速度时添加了一个判断。以后便能正常运做了。
var x = e.touches[0].pageX; var t = (new Date).getTime(); var dt = Math.max((t - curT) / 20, 1); if( Math.abs(x - curX) > 1) { speedX = Math.floor((x - curX) / dt); curX = x; curT = t; }