移動互聯網終端的touch事件,touchstart, touchend, touchmove 很棒的文章


諸如智能手機和平板電腦一類的移動設備一般會有一個電容式觸摸屏(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應用同樣。

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

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

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

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

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

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

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屬性)。這個對象包括一些重要的屬性:canvas

client / clientY:觸摸點相對於瀏覽器窗口viewport的位置數組

pageX / pageY:觸摸點相對於頁面的位置瀏覽器

screenX /screenY:觸摸點相對於屏幕的位置網絡

identifier: touch對象的unique ID

咱們從一個單根手指觸摸的實例開始進入多觸式網頁的世界。當一根手指放下的時候,屏幕上出現一個方塊,手指移動方塊也隨着移動,手指提起方塊消失。首先,讓咱們定義一下方塊的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);

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

相關文章
相關標籤/搜索