諸如智能手機和平板電腦一類的移動設備一般會有一個電容式觸摸屏(capacitive touch-sensitive screen),以捕捉用戶的手指所作的交互。隨着移動網絡的發展,其可以支持愈來愈複雜的應用,web開發者須要一種方法來處理這些事件。例如,幾乎所 有的快節奏遊戲都須要玩家一次按下多個按鈕,這種方式,在觸摸屏狀況下,意味着多點觸摸。Apple在iOS 2.0中引入了觸摸事件API,Android正迎頭遇上這一事實標準,縮小差距。最近一個W3C工做組正協力制定這一觸摸事件規範。
iOS上的Safari也支持click 和mouseover等傳統的交互事件,只是不推薦在iOS的瀏覽器應用上使用click和mouseover,由於這兩個事件是爲了支持鼠標點擊而設計 出來的。Click事件在iOS上會有半秒左右的延遲,緣由是iOS要highlight接收到click的element。而 mouseover/out等事件則會被手指的點擊觸發。因此,在iOS上,應當拋棄傳統的交互事件模型而接受一個新的事件模型。Touch事件和更高級 的Gesture事件,能讓你的網頁交互起來像native應用同樣。
三種在規範中列出並得到跨移動設備普遍實現的基本觸摸事件:javascript
1. touchstart :手指放在一個DOM元素上。
2. touchmove :手指拖曳一個DOM元素。
3. touchend :手指從一個DOM元素上移開。
每一個觸摸事件都包括了三個觸摸列表:css
1. touches :當前位於屏幕上的全部手指的一個列表。
2. targetTouches :位於當前DOM元素上的手指的一個列表。
3. changedTouches :涉及當前事件的手指的一個列表。html
例如,在一個touchend事件中,這就會是移開的手指。
這些列表由包含了觸摸信息的對象組成:前端
1. identifier :一個數值,惟一標識觸摸會話(touch session)中的當前手指。
2. target :DOM元素,是動做所針對的目標。
3. 客戶/頁面/屏幕座標 :動做在屏幕上發生的位置。
4. 半徑座標和 rotationAngle :畫出大約至關於手指形狀的橢圓形。
在開始描述touch事件以前,須要先描述一下多觸式系統中特有的touch對象(android和iOS乃至nokia最新的meego系統都模擬了類 似的對象,這裏只針對iOS,由於我只有iPad可用於測試。。)。這個對象封裝一次屏幕觸摸,通常來自於手指。它在touch事件觸發的時候產生,能夠 經過touch event handler的event對象取到(通常是經過event.changedTouches屬性)。這個對象包括一些重要的屬性:html5
client / clientY:觸摸點相對於瀏覽器窗口viewport的位置java
pageX / pageY:觸摸點相對於頁面的位置jquery
screenX /screenY:觸摸點相對於屏幕的位置android
identifier: touch對象的unique IDcss3
咱們從一個單根手指觸摸的實例開始進入多觸式網頁的世界。當一根手指放下的時候,屏幕上出現一個方塊,手指移動方塊也隨着移動,手指提起方塊消失。首先,讓咱們定義一下方塊的css:web
*{margin:0;padding:0}
html,body{height:100%}
.spirit{position:absolute;width:50px;height:50px;background-color:red;}
#canvas{position:relative;width:100%;height:200px;background-color:#ccc}
而後,在body下定義一個接收事件的容器:
<div id="canvas"></div>
定義touchstart的事件處理函數,並綁定事件:
var canvas = document.getElementById("canvas"), spirit, startX, startY; function touchStart(event) { //阻止網頁默認動做(即網頁滾動) event.preventDefault(); if (spirit || !event.touches.length) return; var touch = event.touches[0]; startX = touch.pageX; startY = touch.pageY; spirit = document.createElement("div"); canvas.appendChild(spirit); spirit.className = "spirit"; spirit.style.left = startX + "px"; spirit.style.top = startY + "px"; } canvas.addEventListener("touchstart", touchStart, false);
首先,咱們將方塊spirit做爲一個全局對象,由於咱們如今要測試單根手指因此屏幕上最好只有一個物體在移動(等會有多觸實例)。在touchStart這個事件處理函數中,咱們也首先判斷了是否已經產生了spirit,也就是是否已經有一個手指放到屏幕上,若是是,直接返回。
和傳統的event listener同樣,多觸式系統也會產生一個event對象,只不過這個對象要多出一些屬性,好比這裏的event.touches,這個數組對象得到屏幕上全部的touch。注意這裏的event.preventDefault(),在傳統的事件處理函數中,這個方法阻止事件的默認動做,觸摸事件的默認動做是滾屏,咱們不想屏幕動來動去的,因此先調用一下這個函數。咱們取第一個touch,將其pageX/Y做爲spirit建立時的初始位置。接下來,咱們建立一個div,而且設置className,left,top三個屬性。最後,咱們把spirit對象appendChild到容器中。這樣,當第一根手指放下的時候,一個紅色的,50px見方的方塊就放到屏幕上了。
而後,咱們要開始處理手指在屏幕上移動的事件:
function touchMove(event) {
event.preventDefault();
if (!spirit || !event.touches.length) return;
var touch = event.touches[0],
x = touch.pageX - startX,
y = touch.pageY - startY;
//這裏是爲了手指必定是橫向滾動的,原理是計算X位置的偏移要比Y的偏移大
if (Math.abs(x) > Math.abs(y)) {
spirit.style.left = touch.pageX + "px";
spirit.style.top = touch.pageY + "px";
}
}
canvas.addEventListener("touchmove", touchMove, false);
在touch move listener中,咱們使用webkit特有的css屬性:webkitTransform來移動方塊,這個屬性具體怎麼用請google之。建議構造面向iOS設備的網頁的時候儘可能使用webkit本身的特性,不但炫,更能夠直接利用硬件來提升性能。
最後,咱們處理touchend事件。手指提起的時候方塊從屏幕上移除。
function touchEnd(event) { if (!spirit) return; canvas.removeChild(spirit); spirit = null; } canvas.addEventListener("touchend", touchEnd, false);
在你的ipad或者iphone上測試一下以上代碼。若是不出意外的話,一個完整的多觸式web程序就誕生了。。
設備支持
遺憾的是,觸摸事件的實如今完備性和質量方面的差異很大。我編寫了一個診斷腳原本顯示一些關於觸摸API實現的基本信息,其中包括哪些事件是支持 的,以及 touchmove事件觸發的解決方案。我在Nexus One和Nexus S硬件上測試了Android 2.3.3,在Xoom上測試了Android 3.0.1,以及在iPad和iPhone上測試了iOS 4.2。
簡而言之,全部被測試的瀏覽器都支持touchstart、touchend和touchmove事件。
規範提供了額外的三個觸摸事件,但被測試的瀏覽器沒有支持它們:
1. touchenter :移動的手指進入一個DOM元素。
2. toucheleave :移動手指離開一個DOM元素。
3. touchcancel :觸摸被中斷(實現規範)。
被測試的瀏覽器還在每一個觸摸列表內部都提供了touches、targetTouches和changedTouches列表。不過,被測試的瀏 覽器沒有支持 radiusX、radiusY或是rotationAngle屬性,這些屬性指明觸摸屏幕的手指的形狀。在一次touchmove期間,事件大約一秒鐘 觸發60次,全部的被測試設備都是這樣。
<html xmlns="http://www.w3.org/1999/xhtml"><head> <title></title> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"> <script id="others_zepto_10rc1" type="text/javascript" class="library" src="http://sandbox.runjs.cn/js/sandbox/other/zepto.min.js"></script> </head> <body> <div id="d" style=" width: 100px; height: 100px; border: 1px solid black;"></div> <div id="d2" style=" width: 100px; height: 100px; border: 1px solid orange;"></div> <script type="text/javascript"> var startTime; var t = false, m = false; var log = function (msg) { var div = $('<div></div>'); div.html((new Date().getTime()) + ': ' + (new Date().getTime() - startTime) + ': ' + msg) $('body').append(div); }; var touchStart = function () { log('start'); startTime = new Date().getTime(); t = true; log('touchStart'); }; var touchEnd = function () { t = false; log('touchEnd'); }; var touchMove = function (e) { e.preventDefault(); if (!t) return false; log('touchMove'); }; var mouseDown = function (e) { e.preventDefault(); startTime = startTime || new Date().getTime(); m = true; log('mouseDown'); }; var mouseClick = function () { log('mouseClick'); }; var mouseUp = function () { m = false; log('mouseUp'); }; var mouseMove = function (e) { e.preventDefault(); if (!m) return; log('mousemove'); }; var d = $('#d'); var dd = $('#d2'); dd.bind('mousedown', mouseDown); dd.bind('click', mouseClick); dd.bind('mouseup', mouseUp); dd.bind('mousemove', mouseMove); d.bind('touchstart', touchStart); d.bind('touchend', touchEnd); d.bind('touchmove', touchMove); </script> <style></style> <script></script> <!-- Generated by RunJS (Fri Jul 03 09:54:14 CST 2015) 0ms --></body></html>
處理Touch事件能讓你跟蹤用戶的每一根手指的位置。你能夠綁定如下四種Touch事件:
1、
touchstart:// 手指放到屏幕上的時候觸發
touchmove:// 手指在屏幕上移動的時候觸發
touchend:// 手指從屏幕上拿起的時候觸發
touchcancel:// 系統取消touch事件的時候觸發。至於系統何時會取消,不詳
2、
client / clientY:// 觸摸點相對於瀏覽器窗口viewport的位置
pageX / pageY:// 觸摸點相對於頁面的位置
screenX /screenY:// 觸摸點相對於屏幕的位置
identifier:>// touch對象的unique ID
三,
每一個Touch對象包含下列屬性。
clientX:觸摸目標在視口中的X座標。
clientY:觸摸目標在視口中的Y座標。
identifier:表示觸摸的惟一ID。
pageX:觸摸目標在頁面中的x座標。
pageY:觸摸目標在頁面中的y座標。
screenX:觸摸目標在屏幕中的x座標。
screenY:觸摸目標在屏幕中的y座標。
target:觸摸的DOM節點座標。
<!doctype html> <html> <head> <meta charset="utf-8"> <title>touches</title> <style> body{ font-size:60px; color:red;} </style> <script> function touches(ev){ if(ev.touches.length==1){ var oDiv=document.getElementById('div1'); switch(ev.type){ case 'touchstart': oDiv.innerHTML='Touch start('+ev.touches[0].clientX+', '+ev.touches[0].clientY+')'; ev.preventDefault(); //阻止出現滾動條 break; case 'touchend': oDiv.innerHTML='Touch end('+ev.changedTouches[0].clientX+', '+ev.changedTouches[0].clientY+')'; break; case 'touchmove': oDiv.innerHTML='Touch move('+ev.changedTouches[0].clientX+', '+ev.changedTouches[0].clientY+')'; break; } } } document.addEventListener('touchstart',touches,false); document.addEventListener('touchend',touches,false); document.addEventListener('touchmove',touches,false); </script> </head> <body> <div id="div1"></div> </body> </html>
2、手勢事件:
gesturestart: 當一個手指按在屏幕上,另外一個手指有觸發屏幕時,觸發;
gestureend: 當你的任何一個手指從屏幕上移開的時候,觸發;
gesturechange: 當觸摸屏幕的任何一個手指發生變化的時候,觸發;
在事件對象這裏,其餘的都還同樣,在手勢這裏多了兩個頗有用的東西:
一個是rotation: 手指變化引發的旋轉角度,順時針爲正的,逆時針爲負的;
還有一個scale: 兩個手指之間的距離變化;
<!doctype html> <html> <head> <meta charset="utf-8"> <title>gesture</title> <style> body{ font-size:60px; color:red;} </style> <script> window.onload=function(){ function gesture(ev){ var div=document.getElementById('div1'); switch(ev.type){ case 'gesturestart': div.innerHTML='Gesture start (rotation='+ev.rotation+', scale='+ev.scale+')'; ev.preventDefault(); break; case 'gestureend': div.innerHTML='Gesture End (rotation='+ev.rotation+', scale='+ev.scale+')'; break; case 'gesturechange': div.innerHTML='Gesture Change (rotation='+ev.rotation+', scale='+ev.scale+')'; break; } } document.addEventListener('gesturestart',gesture,false); document.addEventListener('gestureend',gesture,false); document.addEventListener('gesturechange',gesture,false); } </script> </head> <body> <div id="div1"></div> </body> </html>
如今jquery提供了一個很是不錯的jquery手機插件,就是jquery mobile了,使用它就能夠很方便哦。
摘自網絡