移动互联网终端的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次,全部的被测试设备都是这样。

相关文章
相关标签/搜索