移動互聯網終端的touch事件,touchstart, touchend, touchmove

前言

若是咱們容許用戶在頁面上用相似桌面瀏覽器鼠標手勢的方式來控制WEB APP,這個頁面上確定是有不少可點擊區域的,若是用戶觸摸到了那些可點擊區域怎麼辦呢??
諸如智能手機和平板電腦一類的移動設備一般會有一個電容式觸摸屏(capacitive touch-sensitive screen),以捕捉用戶的手指所作的交互。隨着移動網絡的發展,其可以支持愈來愈複雜的應用,web開發者須要一種方法來處理這些事件。例如,幾乎所 有的快節奏遊戲都須要玩家一次按下多個按鈕,這種方式,在觸摸屏狀況下,意味着多點觸摸。
Apple在iOS 2.0中引入了觸摸事件API,Android正迎頭遇上這一事實標準,縮小差距。最近一個W3C工做組正協力制定這一觸摸事件規範。
在本文中,我會深刻研究iOS和Android設備提供的觸摸事件API,探索一下能夠構建哪些類型的應用,給出一些最佳作法,並論及一些使得可觸控應用(touch-enabled application)的開發變得更加容易的有用技術。javascript

觸摸事件html


三種在規範中列出並得到跨移動設備普遍實現的基本觸摸事件:html5

1. touchstart :手指放在一個DOM元素上。
2. touchmove :手指拖曳一個DOM元素。
3. touchend :手指從一個DOM元素上移開。java

每一個觸摸事件都包括了三個觸摸列表:react

1. touches :當前位於屏幕上的全部手指的一個列表。
2. targetTouches :位於當前DOM元素上的手指的一個列表。
3. changedTouches :涉及當前事件的手指的一個列表。android

例如,在一個touchend事件中,這就會是移開的手指。git

這些列表由包含了觸摸信息的對象組成:github

1. identifier :一個數值,惟一標識觸摸會話(touch session)中的當前手指。
2. target :DOM元素,是動做所針對的目標。
3. 客戶/頁面/屏幕座標 :動做在屏幕上發生的位置。
4. 半徑座標和 rotationAngle :畫出大約至關於手指形狀的橢圓形。web

可觸控應用canvas


touchstart、touchmove和touchend事件提供了一組足夠豐富的功能來支持幾乎是任何類型的基於觸摸的交互——其中包括常見的多點觸摸手勢,好比說捏縮放、旋轉等待。

下面的這段代碼讓你使用單指觸摸來四處拖曳一個DOM元素:

var obj = document.getElementById('id'); 
obj.addEventListener('touchmove', function(event) { 
// 若是這個元素的位置內只有一個手指的話 
if (event.targetTouches.length == 1) { 
var touch = event.targetTouches[0]; 
// 把元素放在手指所在的位置 
obj.style.left = touch.pageX + 'px'; 
obj.style.top = touch.pageY + 'px'; 
} 
}, false);

下面是一個示例,該例子顯示了屏幕上當前全部的觸點,它的做用就是用來感覺一下設備的響應性。

// 設置畫布並經過ctx變量來暴露上下文 
canvas.addEventListener('touchmove', function(event) { 
for (var i = 0; i < event.touches.length; i++) { 
var touch = event.touches[i]; 
ctx.beginPath(); 
ctx.arc(touch.pageX, touch.pageY, 20, 0, 2*Math.PI, true); 
ctx.fill(); 
ctx.stroke(); 
} 
}, false);

演示

處處都有着許多有意思的多點觸摸演示,好比說這個由Paul Irish和其餘人實現的基於畫布的繪畫演示 。

還有Browser Ninja ,一個技術演示 , 是一個使用了CSS3的轉換、過渡和畫布的Fruit Ninja克隆。

最佳作法


阻止縮放

缺省的多點觸摸設置不是特別的好用,由於你的滑動和手勢每每與瀏覽器的行爲有關聯,好比說滾動和縮放。

要禁用縮放功能的話,使用下面的元標記設置你的視圖區(viewport),這樣其對於用戶來講就是不可伸縮的了:

content="width=device-width, initial-scale=1.0, user-scalable=no"> 

看看這篇關於移動HTML 5 的文章,瞭解更多關於視圖區設置的信息。

阻止滾動

一些移動設備有缺省的touchmove行爲,好比說經典的iOS overscroll效果,當滾動超出了內容的界限時就引起視圖反彈。這種作法在許多多點觸控應用中會帶來混亂,但要禁用它很容易。

document.body.addEventListener('touchmove', function(event) { 
event.preventDefault(); 
}, false);

細心渲染 

若是你正在編寫的多點觸控應用涉及了複雜的多指手勢的話,要當心地考慮如何響應觸摸事件,由於一次要處理這麼多的事情。考慮一下前面一節中的在屏幕上畫出全部觸點的例子,你能夠在有觸摸輸入的時候就馬上進行繪製:

canvas.addEventListener('touchmove', function(event) { 
renderTouches(event.touches); 
},

不過這一技術並非要隨着屏幕上的手指個數的增多而擴充,替代作法是,能夠跟蹤全部的手指,而後在一個循環中作渲染,這樣可得到更好的性能:

var touches = [] 
canvas.addEventListener('touchmove', function(event) { 
touches = event.touches; 
}, false); 

// 設置一個每秒60幀的定時器 
timer = setInterval(function() { 
renderTouches(touches); 
}, 15);

提示 :setInterval不太適合於動畫,由於它沒有考慮 到瀏覽器本身的渲染循環。現代的桌面瀏覽器提供了requestAnimationFrame這一函數,基於性能和電池工做時間緣由,這是一個更好的選 擇。一但瀏覽器提供了對該函數的支持,那將是首選的處理事情的方式。

使用targetTouches和changedTouches

要記住的一點是,event.touches是與屏幕接觸的全部手指的一個數組,而不只是位於目標DOM元素上的那些。你可能會發現使用 event.targetTouches和event.changedTouches來代替event.touches更有用一些。

最後一點,由於你是在爲移動設備作開發,所以你應該要留心移動的最佳作法,這些在Eric Bidelman的文章 中有論及,以及要了解這一W3C文檔 。

設備支持


遺憾的是,觸摸事件的實如今完備性和質量方面的差異很大。我編寫了一個診斷腳原本顯示一些關於觸摸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次,全部的被測試設備都是這樣。

Android 2.3.3 (Nexus)

Android的Gingerbread瀏覽器(在Nexus One和Nexus S上測試)不支持多點觸摸,這是一個已知的問題 。

Android 3.0.1 (Xoom)

Xoom的瀏覽器對多點觸摸有一個基本的支持,不過只能是在單個的DOM元素上起做用。瀏覽器不能正確響應同時發生在不一樣DOM元素上的兩處觸摸,換句話說,下面的代碼會對兩個同時發生的觸摸的給出反應:

obj1.addEventListener('touchmove', function(event) { 
for (var i = 0; i < event.targetTouches; i++) { 
var touch = event.targetTouches[i]; 
console.log('touched ' + touch.identifier); 
} 
}, false);

但下面的代碼則不會:

var objs = [obj1, obj2]; 
for (var i = 0; i < objs.length; i++) { 
var obj = objs[i]; 
obj.addEventListener('touchmove', function(event) { 
if (event.targetTouches.length == 1) { 
console.log('touched ' + event.targetTouches[0].identifier); 
} 
}, false); 
}

iOS 4.x (iPad, iPhone)

iOS設備徹底支持多點觸摸,可以跟蹤多個手指,並在瀏覽器中提供一個很是敏感的觸摸體驗。

開發者工具


在移動開發中,一種較爲容易的作法是,先在桌面上開始原型設計,而後再在打算要支持的設備上處理移動特有的部分。多點觸摸正是難以在PC上進行測試的那些功能之一,由於大部分的PC都沒有觸摸輸入。

不得不在移動設備上進行的測試有可能會拉長你的開發週期,由於你所作的每項改變都須要提交代碼到服務器上,接着再加載到設備上。而後,一旦運行後,對應用也就沒有太多的調試了,由於平板電腦和智能手機都很缺少web開發者所用的工具。

這個問題的一個解決方案是在開發機器上模擬觸發事件。對於單點觸摸,觸摸事件能夠基於鼠標事件來模擬。若是你有觸摸輸入設備的話,好比說現代的App MacBook,那麼多點觸摸也能夠被模擬。

單點觸摸事件

若是你想在桌面上模擬單點觸摸事件的話,試一下Phantom Limb ,該程序在網頁上模擬觸摸事件並提供一隻巨手來引導。

另外還有Touchable 這一jQuery插件,該插件跨平臺地統一了觸摸和鼠標事件。

多點觸摸事件

爲了可以讓你的多點觸摸web應用在你的瀏覽器或是多點觸摸控板(好比說Apple MacBook或是MagicPad)上起做用,我建立了這一個MagicTouch.js填充工具 ,其捕捉來自觸控板的觸摸事件,而後把它們轉換成標準兼容的觸摸事件。

1. 下載npTuioClient NPAPI插件 並把它安裝到~/Library/Internet Plug-Ins/目錄下。

2. 下載這一Mac MagicPad的TongSeng TUIO應用 並啓動這一服務器。

3. 下載MagicTouch.js 這一javascript庫來基於npTuioClient回調模擬規範兼容的觸摸事件。

4. 以以下方式把magictouch.js腳本和npTuioClient插件包含到你的應用中:

< head> 
... 
< script src="/path/to/magictouch.js" kesrc="/path/to/magictouch.js">< /script> 
< /head> 

< body> 
... 
< object id="tuio" type="application/x-tuio" style="width: 0px; height: 0px;"> 
Touch input plugin failed to load! 
< /object> 
< /body>

我只在Chrome 10上測試了這一方法,不過只要稍作調整它應該可以在其餘的現代瀏覽器上工做。

若是你的計算機沒有多點觸摸輸入的話,你可使用其餘的TUIO跟蹤器,好比說reacTIVision 來模擬觸摸事件。欲瞭解更多信息,請參閱TUIO項目頁面 。

須要注意的一點是,你的手勢能夠是和OS層面的多點觸摸手勢相同的。在OS X上,你能夠經過進入System Preferences中的Trackpad偏好設定版面來配置系統範圍的事件。

隨着多點觸摸功能逐漸獲得跨移動瀏覽器的的普遍支持,我很是高興地看到新的web應用充分利用了這一豐富的API。

轉自:http://select.yeeyan.org/view/213582/202991

相關文章
相關標籤/搜索