hammer.js是一個多點觸摸手勢庫,能夠為網頁加入Tap、Double Tap、Swipe、Hold、Pinch、Drag等多點觸摸事件,免去自己監聽底層touchstart、touchmove、touchend事件并且寫一大堆判斷邏輯的痛苦。hammer.js不但支持觸摸屏設備的瀏覽器,在桌面瀏覽器上,也能將鼠標的點擊當做觸摸,方便開發人員在桌面瀏覽器上調試。這是一個專為觸摸手勢而生的js庫,對有需要的朋友非常有幫助,奉上常用的一些方法調用文檔。
使用方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <script src= "http://eightmedia.github.com/hammer.js/hammer.js" ></script> var ?hammer = new ?Hammer(document.getElementById( "container" )); hammer.ondragstart = function (ev) { };? hammer.ondrag = function (ev) { }; hammer.ondragend = function (ev) { }; hammer.onswipe = function (ev) { }; hammer.ontap = function (ev) { }; hammer.ondoubletap = function (ev) { }; hammer.onhold = function (ev) { }; hammer.ontransformstart = function (ev) { }; hammer.ontransform = function (ev) { }; hammer.ontransformend = function (ev) { }; hammer.onrelease = function (ev) { }; |
還支持jQuery插件的形式調用
1 2 3 4 5 6 7 8 9 | <script src= "http://eightmedia.github.com/hammer.js/jquery.hammer.js" ></script> $( "#element" ) ??? .hammer({ ???????? ??? }) ??? .bind( "tap" , function (ev) { ???????? console.log(ev); ??? }); |
官網地址:http://eightmedia.github.com/hammer.js/? (帶演示)
源碼地址:https://github.com/EightMedia/hammer.js
一、前言
移動端框架當前還處在初級階段,但相對于移動端的應用來說已經有很長時間了。雖然暫時還沒有PC端開發的需求量大,但移動端的Web必然是一種趨 勢,在接觸移動端腳本的過程中,最開始想到的是juqery。Jquery2.0版本及以上已經開始偏向移動端,如對h5的支持,但支持還是不夠完善,希 望jq在后面的版本能夠逐漸支持起來。
最初在開發移動端Web的時候使用w3c標準的語法結構和原生的js開發,但相對來說開發量比較大,而且每一步都要考慮各移動端瀏覽器的兼容,像比 較讓程序員頭痛的大wp手機,很多事件都向w3c申請單獨的標準。因此一個好的兼容性架構對于開發者來說可以節省很大一部分工作量。
剛開始接觸移動端框架之初也問了一些一直搞前端的朋友,大部份都在百度阿里等工作。參考大家的建議后我們做項目使用了zepto.js(很多搞前端 的朋友應該并不陌生)。這個框架有個很大的問題就是不兼容wp手機,使用zepto.js開發完項目后,再針對wp手機兼容做調整總感覺有些“得不償 失”,后來咨詢了些朋友,他們所在的公司在開發的時候基本都放棄wp的兼容(我只能對wp說“呵呵”了)。后面就咨詢到有用hammer.js進行開發 的。我們研究了下,hammer.js輕量級,封裝的也比較好。用起來也很方便。兼容性也不錯。但網上中文資料比較少,園子寫hammer的就更少了。因 此有了這篇文章。
此文章基于hammer.js 官網:http://hammerjs.github.io/?,版本基于v2.0.4。如果該文章的api已過期,請自行到官網查詢最新api。此文章只做入門使用。
二、hammer.js是什么
hammer.js是一款開源的移動端腳本框架,他可以完美的實現在移端開發的大多數事件,如:點擊、滑動、拖動、多點觸控等事件。不需要依賴任何其他的框架,并且整個框架非常小,\在使用時非常簡單,代碼示例如下:
1 <div id="test" class="test"></div> 2 <script type="text/javascript"> 3 //創建一個新的hammer對象并且在初始化時指定要處理的dom元素 4 var hammertime = new Hammer(document.getElementById("test")); 5 //為該dom元素指定觸屏移動事件 6 hammertime.on("pan", function (ev) { 7 //控制臺輸出 8 console.log(ev); 9 }); 10 </script>

三事件架構
hammer.js主要針對觸屏的6大事件進行監聽。如下圖所示:
1、? Pan事件:在指定的dom區域內,一個手指放下并移動事件,即觸屏中的拖動事件。這個事件在屏觸開發中比較常用,如:左拖動、右拖動等,如手要上使用QQ時向右滑動出現功能菜單的效果。該事件還可以分別對以下事件進行監聽并處理:
Panstart:拖動開始、Panmove:拖動過程、Panend:拖動結束、Pancancel:拖動取消、Panleft:向左拖動、Panright:向右拖動、Panup:向上拖動、Pandown:向下拖動
2、? Pinch事件:在指定的dom區域內,兩個手指(默認為兩個手指,多指觸控需要單獨設置)或多個手指相對(越來越近)移動或相向(越來越遠)移動時事件。該事件事以分別對以下事件進行監聽并處理:
Pinchstart:多點觸控開始、Pinchmove:多點觸控過程、Pinchend:多點觸控結束、Pinchcancel:多點觸控取消、Pinchin:多點觸控時兩手指距離越來越近、Pinchout:多點觸控時兩手指距離越來越遠
3、? Press事件:在指定的dom區域內觸屏版本的點擊事件,這個事件相當于PC端的Click事件,該不能包含任何的移動,最小按壓時間為500毫秒,常用于我們在手機上用的“復制、粘貼”等功能。該事件分別對以下事件進行監聽并處理:
Pressup:點擊事件離開時觸發
4、? Rotate事件:在指定的dom區域內,當兩個手指或更多手指成圓型旋轉時觸發(就像兩個手指擰螺絲一樣)。該事件分別對以下事件進行監聽并處理:
Rotatestart:旋轉開始、Rotatemove:旋轉過程、Rotateend:旋轉結束、Rotatecancel:旋轉取消
5、? Swipe事件:在指定的dom區域內,一個手指快速的在觸屏上滑動。即我們平時用到最多的滑動事件。
Swipeleft:向左滑動、Swiperight:向右滑動、Swipeup:向上滑動、Swipedown:向下滑動
6、Tap事件:在指定的dom區域內,一個手指輕拍或點擊時觸發該事件(類似PC端的click)。該事件最大點擊時間為250毫秒,如果超過250毫秒則按Press事件進行處理。
經驗分享:寫到這個事件的時候有人必然要問了,在觸屏中我們使用Click事件不也可以嗎?這個Tap事件與Click事件有什么區別呢?博主也曾 經有過這樣的疑惑,起初在觸屏上處理點擊的時候也一直用的click事件,并且沒也有出現任何問題,直到有一天為一個公司做了微信版本的“連連看”小游 戲,連連看的業務簡單來說就是屏幕上有很多圖片,當點擊兩個相同圖案的圖片時可以在中間產生連接線,并且產生爆破效果后消失。這個游戲剛開始做的時候是在 ff瀏覽器上做的測試,鼠標點擊后效果非常流暢,但當游戲部署到服務器上并用手機端操作時,iphone和wp都非常流暢,安卓下不管怎么調都是有卡頓。 起初以為是手機性能的問題,但換了高配手機后仍然會有卡頓,游戲也不是不能玩,就是反應慢。經過多次的測試后排除了手機配置的硬件原因,開始懷疑 click事件。經過網上查閱后才得知,在安卓觸屏上,Tap事件和click事件可以同時觸發,但click事件會有幾百毫秒的延遲,即先觸發Tap事 件,過一段時間再觸發click事件。后來把游戲的所有click事件修改成Tap事件問題就自然解決了。
四、 使用實例
1、?Pan
代碼如下:
1 <!DOCTYPE html>2 <html> 3 <head> 4 <meta name="viewport" content="width=device-width" /> 5 <title>Pan</title> 6 <script src="/Script/hammer.js"></script> 7 <style type="text/css"> 8 html, body { 9 width: 100%; 10 height: 100%; 11 margin: 0px; 12 padding: 0px; 13 } 14 15 .test { 16 width: 100%; 17 height: 50%; 18 background: #ffd800; 19 text-align: left; 20 } 21 22 .result { 23 width: 100%; 24 height: 50%; 25 background: #b6ff00; 26 text-align: left; 27 } 28 </style> 29 </head> 30 <body> 31 <div id="test" class="test">事件區域</div> 32 <div id="result" class="result">事件結果<br /></div> 33 <script type="text/javascript"> 34 //創建一個新的hammer對象并且在初始化時指定要處理的dom元素 35 var hammertime = new Hammer(document.getElementById("test")); 36 //添加事件 37 hammertime.on("pan", function (e) { 38 document.getElementById("result").innerHTML += "X偏移量:【" + e.deltaX + "】,Y偏移量:【" + e.deltaY + "】<br />"; 39 //控制臺輸出 40 console.log(e); 41 }); 42 </script> 43 </body> 44 </html>

效果如下:

2、Pinch
代碼如下:
1 <!DOCTYPE html>2 <html> 3 <head> 4 <meta name="viewport" content="width=device-width" /> 5 <title>Pinch</title> 6 <script src="/Script/hammer.js"></script> 7 <style type="text/css"> 8 html, body { 9 width: 100%; 10 height: 100%; 11 margin: 0px; 12 padding: 0px; 13 } 14 15 .test { 16 width: 100%; 17 height: 50%; 18 background: #ffd800; 19 text-align: left; 20 } 21 22 .result { 23 width: 100%; 24 height: 50%; 25 background: #b6ff00; 26 text-align: left; 27 } 28 </style> 29 </head> 30 <body> 31 <div id="test" class="test">事件區域</div> 32 <div id="result" class="result">事件結果:捏合觸發<br /></div> 33 <script type="text/javascript"> 34 //創建一個新的hammer對象并且在初始化時指定要處理的dom元素 35 var hammertime = new Hammer(document.getElementById("test")); 36 //為該dom元素指定觸屏移動事件 37 hammertime.add(new Hammer.Pinch()); 38 //添加事件 39 hammertime.on("pinchin", function (e) { 40 document.getElementById("result").innerHTML += "捏合初觸發<br />"; 41 //控制臺輸出 42 console.log(e); 43 }); 44 </script> 45 </body> 46 </html>

效果如下:

3、Press
代碼如下:
1 <!DOCTYPE html>2 <html> 3 <head> 4 <meta name="viewport" content="width=device-width" /> 5 <title>Press</title> 6 <script src="/Script/hammer.js"></script> 7 <style type="text/css"> 8 html, body { 9 width: 100%; 10 height: 100%; 11 margin: 0px; 12 padding: 0px; 13 } 14 15 .test { 16 width: 100%; 17 height: 50%; 18 background: #ffd800; 19 text-align: left; 20 } 21 22 .result { 23 width: 100%; 24 height: 50%; 25 background: #b6ff00; 26 text-align: left; 27 } 28 </style> 29 </head> 30 <body> 31 <div id="test" class="test">事件區域</div> 32 <div id="result" class="result">事件結果:按壓超過500ms觸發<br /></div> 33 <script type="text/javascript"> 34 //創建一個新的hammer對象并且在初始化時指定要處理的dom元素 35 var hammertime = new Hammer(document.getElementById("test")); 36 //添加事件 37 hammertime.on("press", function (e) { 38 document.getElementById("result").innerHTML += "超過500ms了<br />"; 39 //控制臺輸出 40 console.log(e); 41 }); 42 </script> 43 </body> 44 </html>
效果如下:

4、Rotate
代碼如下:

1 <!DOCTYPE html>2 <html> 3 <head> 4 <meta name="viewport" content="width=device-width" /> 5 <title>Rotate</title> 6 <script src="/Script/hammer.js"></script> 7 <style type="text/css"> 8 html, body { 9 width: 100%; 10 height: 100%; 11 margin: 0px; 12 padding: 0px; 13 } 14 15 .test { 16 width: 100%; 17 height: 50%; 18 background: #ffd800; 19 text-align: left; 20 } 21 22 .result { 23 width: 100%; 24 height: 50%; 25 background: #b6ff00; 26 text-align: left; 27 } 28 </style> 29 </head> 30 <body> 31 <div id="test" class="test">事件區域</div> 32 <div id="result" class="result">事件結果:旋轉觸發<br /></div> 33 <script type="text/javascript"> 34 //創建一個新的hammer對象并且在初始化時指定要處理的dom元素 35 var hammertime = new Hammer(document.getElementById("test")); 36 //為該dom元素指定觸屏移動事件 37 hammertime.add(new Hammer.Rotate()); 38 //添加事件 39 hammertime.on("rotate", function (e) { 40 document.getElementById("result").innerHTML += "X偏移量:【" + e.deltaX + "】,Y偏移量:【" + e.deltaY + "】<br />"; 41 //控制臺輸出 42 console.log(e); 43 }); 44 </script> 45 </body> 46 </html>

效果如下:

5、Swipe
代碼如下:
1 <!DOCTYPE html>2 <html> 3 <head> 4 <meta name="viewport" content="width=device-width" /> 5 <title>Swipe</title> 6 <script src="/Script/hammer.js"></script> 7 <style type="text/css"> 8 html, body { 9 width: 100%; 10 height: 100%; 11 margin: 0px; 12 padding: 0px; 13 } 14 15 .test { 16 width: 100%; 17 height: 50%; 18 background: #ffd800; 19 text-align: left; 20 } 21 22 .result { 23 width: 100%; 24 height: 50%; 25 background: #b6ff00; 26 text-align: left; 27 } 28 </style> 29 </head> 30 <body> 31 <div id="test" class="test">事件區域</div> 32 <div id="result" class="result">事件結果:向左滑動觸發<br /></div> 33 <script type="text/javascript"> 34 //創建一個新的hammer對象并且在初始化時指定要處理的dom元素 35 var hammertime = new Hammer(document.getElementById("test")); 36 //添加事件 37 hammertime.on("swipeleft", function (e) { 38 document.getElementById("result").innerHTML += "X偏移量:【" + e.deltaX + "】,Y偏移量:【" + e.deltaY + "】<br />"; 39 //控制臺輸出 40 console.log(e); 41 }); 42 </script> 43 </body> 44 </html>
效果如下:

6、Tab
代碼如下:
1 <!DOCTYPE html>2 <html> 3 <head> 4 <meta name="viewport" content="width=device-width" /> 5 <title>Tap</title> 6 <script src="/Script/hammer.js"></script> 7 <style type="text/css"> 8 html, body { 9 width: 100%; 10 height: 100%; 11 margin: 0px; 12 padding: 0px; 13 } 14 15 .test { 16 width: 100%; 17 height: 50%; 18 background: #ffd800; 19 text-align: left; 20 } 21 22 .result { 23 width: 100%; 24 height: 50%; 25 background: #b6ff00; 26 text-align: left; 27 } 28 </style> 29 </head> 30 <body> 31 <div id="test" class="test">事件區域</div> 32 <div id="result" class="result">事件結果:點擊觸發<br /></div> 33 <script type="text/javascript"> 34 //創建一個新的hammer對象并且在初始化時指定要處理的dom元素 35 var hammertime = new Hammer(document.getElementById("test")); 36 //添加事件 37 hammertime.on("tap", function (e) { 38 document.getElementById("result").innerHTML += "點擊觸發了,長按無效<br />"; 39 //控制臺輸出 40 console.log(e); 41 }); 42 </script> 43 </body> 44 </html>
效果如下:

上述的實例還是有所區別的。在Pinch事件和Rotate事件中,我們用了hammertime.add(new Hammer.Pinch());和hammertime.add(new Hammer.Rotate ());而其他四個事件沒有用,而是直接添加了事件的監聽程序。原因在于,我們在new Hammer(htmlElement)的時候,Hammer.js默認對Pan、Press、Swipe和Tab事件進行了監聽。但沒有對Pinch和 Rotate事件進行監聽。