在項目開發過程當中遇到有虛擬鍵盤開發的需求(以下圖),其中刪除鍵須要實現 長按
刪除輸入框所有內容,由此展開今天要討論的 web 手勢
開發內容。git
先放出實現代碼:github
var $input = document.getElementById('input'); var $delBtn = document.getElementById('delBtn'); var delBtnClock = null; $delBtn.ontouchstart = function () { $input.innerHTML = $input.innerHTML.slice(0, -1) delBtnClock = setTimeout(function () { $input.innerHTML = ''; }, 500); } $delBtn.ontouchend = function () { clearTimeout(delBtnClock); delBtnClock = null; }
關鍵代碼就兩句話:web
若是隻是點擊,此時 touchend 距離 touchstart 確定不到 500 ms,計時器在時間沒到前已被刪除,實現的效果就只是退格;若是長按超過 500 ms,計時器執行,實現輸入框內容所有刪除。異步
因此 長按
手勢其實是由 touchstart & touchend & setTimeout 三者共同模擬的效果。學習
實際上,常規的 js 事件只支持 click、touchstart、touchend、touchmove、touchcancel 這五種與點擊相關的事件,若是想實現更多的諸如旋轉、放大縮小之類的手勢的話,就須要結合上面的五種事件和其餘方法來模擬實現了。spa
下面我未來介紹下傳說中的《超級小的 web 手勢庫:AlloyFinger》線程
業內知名的強大的 web 手勢庫 hammer.js,總共有 3240 行代碼,壓縮版的 44.7 kb。與之相比,AlloyFinger 真的稱得上超級小了,326 行代碼,10 倍的差距,在 「kb 必爭」 移動 web 應用裏,AlloyFinger 一下就引發了廣大開發者的注意,代碼量小,功能又齊全,你還要什麼單車呢。(我是否是得找人家要下廣告費)code
在 AlloyFinger 裏,手勢一共有 14 種,除了常規的 4 種 touchstart,touchmove,touchend 和 touchcancel,還有 10 種由以上 4 種衍生出來的手勢以下:生命週期
touchstart 中,觸點多於 1 個時觸發事件
touchend 中,觸點少於 2 個時觸發(一開始還在想是否是 bug,實際的意思是:最後一個手指離開時觸發)
touchend 中,觸點沒有移動(移動橫縱距離小於 30 px),且沒有觸發 longTap 時(距離 touchStart 時間少於 750 ms)觸發
touchend 中,有上一次的點擊記錄 & 點擊時間差小於 250 ms & 兩次點擊間沒有移動(移動橫縱距離小於 30 px)
touchstart 中,添加 750 ms 計時器,在這個時間段內沒有鬆手(touchEnd)移動(touchMove),則觸發
touchend 中,單擊狀況下 250 ms 內沒有再次點擊
touchmove 中,觸點多於 1 個,並存在上一次的多點移動記錄時觸發
touchmove 中,觸點多於 1 個 & 存在上一次的移動記錄 & 有縮放長度記錄時觸發
touchmove 中,觸點等於 1 個
touchmove 中,觸點多於 1 個
touchend 中,觸點有移動(移動橫縱距離大於 30 px)
setTimeout(function () {}, 0);
, 一方面實現同步轉異步,釋放線程,另外一方面也能確保屏幕滾動時阻止事件的觸發滑動時,以最大的移動方向決定水平和豎直方向
_swipeDirection: function (x1, x2, y1, y2) { return Math.abs(x1 - x2) >= Math.abs(y1 - y2) ? (x1 - x2 > 0 ? 'Left' : 'Right') : (y1 - y2 > 0 ? 'Up' : 'Down') }
在閱讀源碼過程當中,對關鍵代碼作了註釋,點我