移動開發框架剖析(一) Hammer專業的手勢控制


一直在寫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步的處理就已經完全足夠了,但是這都不是重點,重點是我們要的不是使用,而且能夠“造輪子”弄懂原理!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM