來源:http://www.css119.com/archives/1629javascript
諸如智能手機和平板電腦一類的移動設備一般會有一個電容式觸摸屏(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應用同樣。
三種在規範中列出並得到跨移動設備普遍實現的基本觸摸事件:css
1. touchstart :手指放在一個DOM元素上。
2. touchmove :手指拖曳一個DOM元素。
3. touchend :手指從一個DOM元素上移開。
每一個觸摸事件都包括了三個觸摸列表:html
1. touches :當前位於屏幕上的全部手指的一個列表。
2. targetTouches :位於當前DOM元素上的手指的一個列表。
3. changedTouches :涉及當前事件的手指的一個列表。前端
例如,在一個touchend事件中,這就會是移開的手指。
這些列表由包含了觸摸信息的對象組成:html5
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屬性)。這個對象包括一些重要的屬性:java
client / clientY:觸摸點相對於瀏覽器窗口viewport的位置jquery
pageX / pageY:觸摸點相對於頁面的位置android
screenX /screenY:觸摸點相對於屏幕的位置css3
identifier: touch對象的unique IDgit
咱們從一個單根手指觸摸的實例開始進入多觸式網頁的世界。當一根手指放下的時候,屏幕上出現一個方塊,手指移動方塊也隨着移動,手指提起方塊消失。首先,讓咱們定義一下方塊的css:
*{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次,全部的被測試設備都是這樣。
開發者工具
在移動開發中,一種較爲容易的作法是,先在桌面上開始原型設計,而後再在打算要支持的設備上處理移動特有的部分。多點觸摸正是難以在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回調模擬規範兼容的觸摸事件。
對touch event的介紹咱們點到爲止,這裏給你們推薦兩篇文檔:
Safari web content guide:
對於有志於開發多觸式網頁應用的程序員來講,apple的developer站點是一個應該常常光顧的地方。
我作的一個簡單的例子:
http://www.css119.com/demo/touchmove.html