一直在寫jQuery的源碼教程,都沒時間研究別的框架了。Hammer是我項目御用的一個手勢庫,早期1.x版本的swipe事件的響應不靈敏的問題而改過源碼,2.x就已經更正過來,而且源碼的結構也整個翻新了一遍,不管從邏輯還是組織結構上,我個人都覺得有必要深入,所以就當作一個系列教程一起學習吧。
本章主要講解下使用,因為官方的API都是英文的,中文資料也相對較少,源碼的分析后續再更新。
通過網方的教程還是有很多地方不是很明白的,可能需要后期看源碼才能弄懂了。
Hammer.js是一個專門用於控制、定制手勢的JavaScript庫。它可以識別出常見的觸摸、拖動、長按、縮放等等,對於希望在網頁上對手勢有所處理的朋友們,應該很有幫助。
官方也表明了2.0版本是完全重寫,包括手勢識別器、和改進支持最近的移動瀏覽器利用touch-action css屬性。同時還支持多種設備,所以多用戶成為可能。功能上更加強大了
使用上很簡單,引入源碼並且創建一個實例。
Hammer
var hammertime = new Hammer(myElement, myOptions); hammertime.on('pan', function(ev) { console.log(ev); });
默認設置下自動添加了,tap、doubletap、press,pan與swipe的橫向滑動,多點觸摸pinch與rotate手勢。
pinch和rotate識別器在默認情況下都是禁用的,因為他們會有元素阻塞,但是我們可以手動開啟:
hammertime.get('pinch').set({ enable: true }); hammertime.get('rotate').set({ enable: true });
當然,我們還可以為pan與swipe 開啟縱向滑動
hammertime.get('pan').set({ direction: Hammer.DIRECTION_ALL });
hammertime.get('swipe').set({ direction: Hammer.DIRECTION_VERTICAL
我們能通過meta的標記,禁用doubletap /觸控放大。但是新的瀏覽器支持touch-action屬性所以可以不需要這個
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">
1.基本的實現
綁定一個簡單的swipe事件,通過回調得到事件的響應
var mc = new Hammer(el); mc.on('swipe',function(evt){ console.log(evt) })
2.改變事件處理的方向
但是默認情況下Hammer是屏蔽了上下滑動的響應的,所以我們如果只指豎向響應,就需要再配置中設置
mc.get('pan').set({ direction: Hammer.DIRECTION_VERTICAL }); mc.on('swipe',function(evt){ console.log(evt) })
我們還可以同時響應橫向與豎向,除此之外,還可以單獨為某個指定的識別器配置
var mc = new Hammer(el); mc.get('swipe').set({ direction: Hammer.DIRECTION_ALL }); mc.on('swipe pan',function(evt){ console.log(evt) })
通過get方法我們可以得到指定對應的識別器,我們這里只給swipe啟動了上下左右滑動的響應,那么pan事件則沒開啟,這種指定特定事件的處理相當的靈活
當然以上都是比較簡單常見的事件處理,如果在一個元素上綁定多個不同的事件處理,那可以引入Hammer.Manager控制了
3.Hammer.Manager
我們可以通過這個Manager設置自己的識別器的實例。可以設置更多的被識別的手勢。
一個復雜的多事件處理的Example https://cdn.rawgit.com/hammerjs/hammer.js/master/tests/manual/visual.html
var mc = new Hammer.Manager(myElement, myOptions); mc.add( new Hammer.Pan({ direction: Hammer.DIRECTION_ALL, threshold: 0 }) ); mc.add( new Hammer.Tap({ event: 'quadrupletap', taps: 4 }) ); mc.on("pan", handlePan); mc.on("quadrupletap", handleTaps);
上面的示例創建一個實例包含一個pan和一個quadrupletap手勢
當然如果我們同時給一個元素上 綁定多個事件用new Hammer(el);直接通過on方法也是可以實現的
但是實際上的測試效果,識別度與靈活度比Hammer.Manager低很多。
因為Manager控制里面,引入了recognizeWith與
requireFailure
用來關聯2個相近的事件,從而提高可用性
var pinch = new Hammer.Pinch(); var rotate = new Hammer.Rotation(); pinch.recognizeWith(rotate);
當然具體內部如何實現,要等以后源碼分解才知道了。官方給的說明確實太少了
最后官方還提到提供一個神秘hammer.input事件,在每一次有用戶交互的時候都會被觸發,可以得到非常有用的數據
hammertime.on("hammer.input", function(ev) { console.log(ev.pointers); });
除此之外,還有很多參數的
比如事件對象,Directions方向,輸入動作Input Events,識別器狀態等等
提供的方法Utils
類似addEventListener的事件綁定與銷毀
Hammer.on(window, "load resize scroll", function(ev) { console.log(ev.type); });
遍歷
Hammer.each([10,20,30,40], function(item, index, src) { });
合並
var options = { b: false }; var defaults = { a: true, b: true, c: [1,2,3] }; Hammer.merge(options, defaults); // options.a == true // options.b == false // options.c == [1,2,3]
extend,inherit,bindFn等等
hammerjs確實很強大,做了市面上大多數的設備的適配,我可以看到源碼中關於適配的代碼就接近一半,整個源碼的結構其實也是比較規整的
大多數人能用1,2步的處理就已經完全足夠了,但是這都不是重點,重點是我們要的不是使用,而且能夠“造輪子”弄懂原理!