诸如智能手机和平板电脑一类的移动设备通常会有一(capacitive touch-sensitivescreen),以捕捉用户的手指所做的交互。随着移动网络的发展,其能够支持越来越复杂的应用,web开发者需要一种方法来处理这些事件。例如,几乎所有的快节奏游戏都需要玩家一次按下多个按钮,这种方式,在触摸屏情况下,意味着多点触摸。

Apple在iOS 2.0中引入了触摸事件API,Android正迎头赶上这一事实标准,缩小差距。最近一个W3C工作组正合力制定这一触摸事件规范

在本文深入研究iOS和Android设备提供的触摸事件API,探索一下可以构建哪些类型的应用,给出一些最佳做法,并论及一些使得可触控应用(touch-enabled application)的开发变得更加容易的有用技术。

触摸事件

三种在规范中列出并获得跨移动设备广泛实现的基本触摸事件:
     1. touchstart:手指放在一个DOM元素上。
     2. touchmove:手指拖曳一个DOM元素。
     3. touchend:手指从一个DOM元素上移开。
     每个触摸事件都包括了三个触摸列表:
     1. touches:当前位于屏幕上的所有手指的一个列表。
     2. targetTouches:位于当前DOM元素上的手指的一个列表。

3. changedTouches:涉及当前事件的手指的一个列表。
     例如,在一个touchend事件中,这就会是移开的手指。
     这些列表由包含了触摸信息的对象组成:
     1. identifier:一个数值,唯一标识触摸会话(touch session)中的当前手指。
     2. target:DOM元素,是动作所针对的目标。
     3. 客户/页面/屏幕坐标:动作在屏幕上发生的位置。
     4. 半径坐标和 rotationAngle:画出大约相当于手指形状的椭圆形。

可触控应用  
     touchstart、touchmove和touchend事件提供了一组足够丰富的功能来支持几乎是任何类型的基于触摸的交互——其中包括常见的多点触摸手势,比如说捏缩放、旋转等待。    下面的这段代码让你使用单指触摸来四处拖曳一个DOM元素:复制代码

var obj = document.getElementByIdx_x_x_x_x_x_x('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;

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硬件上测试了Android2.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;

console.log('touched ' + touch.identifier);

}

}, false);

但下面的代码则不会:复制代码

var objs = [obj1, obj2];

for (var i = 0; i < objs.length; i++) {

var obj = objs;

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。

移动端html touch事件的更多相关文章

  1. 移动端 js touch事件

    随着智能手机和平板电脑的普及, 越来越多的人用移动设备浏览网页,我们平时在pc浏览器上用的鼠标事件,比如:click, mouseover等, 已经无法满足移动设备触摸屏的特点,触摸时代的到来,离不开 ...

  2. 「移动端」touch事件,touchEvent对象

    随着智能手机普及,有越来越多的手机网页和网页版游戏,手机触摸.移动.旋转等等,多种操作.一般电脑的人机交互靠的是鼠标,而手机用的就是触摸.区别有: PC 端一个电脑只能有一个鼠标,而移动端有多点触摸. ...

  3. 移动端的touch事件(一)

    如果我们允许用户在页面上用类似桌面浏览器鼠标手势的方式来控制WEB APP,这个页面上肯定是有很多可点击区域的,如果用户触摸到了那些可点击区域怎么办呢?? 诸如智能手机和平板电脑一类的移动设备通常会有 ...

  4. 浅谈移动端之touch事件--手指的滑动事件

    今天台风‘海马’袭击深圳,全市停工.现分享一篇关于touch的文章,望指教! 原理: 当开始一个touchstart事件的时候,获取此刻手指的横坐标startX和纵坐标startY: 当触发touch ...

  5. 移动端之touch事件--手指的滑动事件

    转自[B5教程网]:http://www.bcty365.com/content-142-5243-1.html 总结:touchmove的最后坐标减去touchstart的起始坐标.X的结果如果正数 ...

  6. 《移动端浏览器Touch事件判断手指滑动方向方法》

    $("body").on("touchstart", function(e) {     e.preventDefault();     startX = e. ...

  7. 对于移动端浏览器touch事件的研究总结(4)判断手指滑动方向

    最近有一些微信的项目,虽然页面很简单,但配合手势后的效果却是很不错的.最基本的效果就是手指向上滑,页面配合css3出现一个展开效果,手指向下滑将展开的内容按原路径收起.其实就是一个简单的判断手指滑动方 ...

  8. 移动端浏览器touch事件的研究总结

    $("body").on("touchstart", function(e) {     e.preventDefault();     startX = e. ...

  9. 移动端开发概览【webview和touch事件】

    作为一个前端,而且作为一个做移动端开发的前端,那意味着你要有三头六臂,跟iOS开发哥哥一起打酱油,跟Android开发哥哥一起修bug... Android vs Ios 我在webkit内核的chr ...

随机推荐

  1. javascript事件中'return false'详解

    浏览器中有很多异步事件,如click,mouseenter,mouseover等等,当用户执行相应操作之后,触发这个事件,然后执行相应的事件处理函数,一般情况下,我们可以通过三种方式给元素添加事件处理 ...

  2. input输入框的readonly属性-----http://www.w3school.com.cn/tags/tag_input.asp

    http://www.w3school.com.cn/tags/tag_input.asp input输入框的readonly属性 查询方法: 1.先找官方的文档,api 2.官方的有看不懂的再百度相 ...

  3. Android BGABadgeView:BGABadgeFrameLayout(5)

     Android BGABadgeView:BGABadgeFrameLayout(5) BGABadgeView除了有自己的线性布局,相对布局外(见附录文章7,8),还实现了FrameLayou ...

  4. markman & psd

    markman & psd MarkMan 设计稿标 & 测量神器 http://www.getmarkman.com/ https://www.jianshu.com/p/83af3 ...

  5. restful(1):序列化

    restful协议中,一切皆是资源,操作只是请求方式 model_to_dict()方法: from django.forms.models import model_to_dict obj = Pu ...

  6. wget: unable to resolve host address “mirrors.163.com” 的解决办法

    wget:无法解析主机地址.这就能看出是DNS解析的问题. 解决办法: 登入root(VPS). 进入/etc/resolv.conf. 修改内容为下nameserver 8.8.8.8 #googl ...

  7. SHARP 加粉

    http://v.ku6.com/show/7ufwm7pqfF8D_f13IdCaag...html

  8. NoSQL数据库概览及其与SQL语法的比較

    [文章摘要] HBase是一个高可靠性.高性能.面向列.可伸缩的分布式存储系统.同一时候也是知名的NoSQL数据库之中的一个.NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤 ...

  9. C Language Study - gets , getchar &amp; scanf

    慢慢的发现C语言功底是如此的薄弱,被这几个字符输入函数搞糊涂了又~~ 来,再来忧伤一次吧~ 那么.我们从scanf開始: 假如说你要将一串字符输入到一字符数组里,例如以下面程序, char a[2]; ...

  10. centos内核编译配置

    1.下载内核,下面是内核官网地址:https://www.kernel.org/ tar.xz    是完整的内核包(完整的内核包是通过两次压缩得到的.一次是xz,一次是tar) pgp      是 ...