本人在作一個簡易項目時,須要實現以下效果:菜單寬度超過屏寬,靠手指左右滑動顯示完成內容(菜單自己仍是二級菜單)數組
很顯然須要用到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; }