• 触摸事件


    三种在规范中列出并跨移动设备广泛实现的基本触摸事件:

    • touchstart:手指放在一个 DOM 元素上。
    • touchmove:手指拖动一个 DOM 元素。
    • touchend:手指从一个 DOM 元素上移开。

    每个触摸事件都包括了三个触摸列表:

    • touches:当前位于屏幕上的所有手指动作的列表。
    • targetTouches:位于当前 DOM 元素上的手指动作的列表。
    • changedTouches:涉及当前事件的手指动作的列表。例如,在一个 touchend 事件中,这将是移开手指。

    这些列表由包含触摸信息的对象组成:

    • identifier:一个数字,用于唯一标识触摸会话中的当前手指。
    • target:作为动作目标的 DOM 元素。
    • 客户端/页面/屏幕坐标:动作在屏幕上发生的位置。
    • 半径坐标和 rotationAngle:画出与手指形状类似的椭圆形。

    可触控的应用程序

    touchstart、touchmove 和 touchend 事件提供了一组足够丰富的功能,可支持几乎任何类型的基于触摸的交互,其中包括所有常见的多点触控手势(如开合缩放、旋转等)。

    下面这段代码可让您使用单指触摸随意拖动一个 DOM 元素:

    var obj = document.getElementById('id');
    obj.addEventListener('touchmove', function(event) {
      // If there's exactly one finger inside this element
      if (event.targetTouches.length == 1) {
        var touch = event.targetTouches[0];
        // Place element where the finger is
        obj.style.left = touch.pageX + 'px';
        obj.style.top = touch.pageY + 'px';
      }
    }, false);

    下面的示例显示了屏幕上当前所有的触点,其作用就是用来感受一下设备的响应性。

    // Setup canvas and expose context via ctx variable
    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) 技术演示: 

    最佳做法

    禁止缩放

    多点触控的默认设置不是很好用,因为您的滑动和手势往往与浏览器的行为有关联,例如滚动和缩放。

    要停用缩放,应使用下面的元标记设置视口,这样用户就无法扩展视口了:

    <meta name="viewport" 
      content="width=device-width, initial-scale=1.0, user-scalable=no">

    有关设置视口的详情,请参阅这篇关于移动 HTML5 的文章

    禁止滚动

    某些移动设备对于 touchmove 有默认的行为,例如经典的 iOS overscroll 特效,会在滚动超出内容的界限时引发视图反弹。这种做法在很多的多点触控应用程序中会带来混乱,不过很容易就能停用:

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

    仔细渲染

    如果您要编写的多点触控应用程序涉及到复杂的多指手势,应仔细考虑如何响应触摸事件,因为需要一次处理很多的事件。请考虑前一章节中在屏幕上绘制所有触点的例子,您可以在有触摸输入的时候就立刻进行绘制:

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

    不过这一技术并不是要随着屏幕上的手指数增多而扩展。您可以改为跟踪所有手指,然后在一个循环中进行渲染,这样获得的性能要好得多:

    var touches = []
    canvas.addEventListener('touchmove', function(event) {
      touches = event.touches;
    }, false);
    
    // Setup a 60fps timer
    timer = setInterval(function() {
      renderTouches(touches);
    }, 15);

    提示:setInterval 不太适于动画,因为它没有考虑到浏览器自身的渲染循环。现代的桌面浏览器提供了 requestAnimationFrame,从性能和电池寿命方面考虑,这是一个更好的选择。因此只要移动浏览器支持这一方式,就应优先选择。

    利用 targetTouches 和 changedTouches

    要记住的一点是,event.touches 是与屏幕接触的所有手指的数组,而不仅仅是位于目标 DOM 元素上的那些。您可能会发现,改用 event.targetTouches 或 event.changedTouches 要更实用一些。

    最后,由于您是针对移动设备进行开发,应该注意移动的最佳做法,这些在埃里克·比德尔曼 (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 事件。

    规范提供了另外三个触摸事件,但测试的浏览器都不支持它们:

    • touchenter:移动的手指进入一个 DOM 元素。
    • touchleave:移动手指离开一个 DOM 元素。
    • 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 都没有触摸输入功能。

    由于不得不在移动设备上进行测试,这样可能会拉长您的开发周期,因为您所做的每项更改都需要提交到服务器,然后再加载到设备上。而一旦运行后,对于应用程序也就没法进行太多调试了,因为平板电脑和智能手机都缺乏网络开发人员所用的工具。

    对于这个问题,一种解决方案就是在开发机器上模拟触发事件。对于单点触摸,触摸事件可以基于鼠标事件来模拟。如果您有支持触摸输入的设备(如时下流行的 Apple MacBook),那么也可以模拟多点触控。

    单点触控事件

    如果您想在桌面上模拟单点触控事件,请尝试使用 Phantom Limb,它可以在网页上模拟触摸事件并提供一只巨手进行引导。

    另外还有 Touchable 这一 jQuery 插件,可跨平台地统一触摸和鼠标事件。

    多点触控事件

    为了能够让您的多点触控网络应用程序在浏览器或多点触控板(如 Apple MacBook 或 MagicPad)上正常使用,我创建了 MagicTouch.js 填充工具,用于捕捉来自触控板的触摸事件,然后将其转换成标准兼容的触摸事件。

    1. 下载 npTuioClient NPAPI 插件 并安装到 ~/Library/Internet Plug-Ins/ 目录下。
    2. 下载适用于苹果机的 MagicPad 的 TongSeng TUIO 应用程序,并启动服务器。
    3. 下载 MagicTouch.js,这是一个 javascript 库,可根据 npTuioClient 回调来模拟规范兼容的触摸事件。
    4. 以如下方式将 magictouch.JS 脚本和 npTuioClient 插件添加到您的应用程序中:
    <head>
      ...
      <script src="/path/to/magictouch.js"></script>
    </head>
    
    <body>
      ...
      <object id="tuio" type="application/x-tuio" style=" 0px; height: 0px;">
        Touch input plugin failed to load!
      </object>
    </body>

    我只在 Chrome 浏览器 10 上测试了这一方法,不过只要稍做调整就应该能够适用于其他的现代浏览器。

  • 相关阅读:
    (转)android res文件夹里面的drawable(ldpi、mdpi、hdpi、xhdpi、xxhdpi)
    ListView模拟微信好友功能
    最小生成树(普利姆算法、克鲁斯卡尔算法)
    Android Afinal框架学习(二) FinalActivity 一个IOC框架
    浅谈WebLogic和Tomcat
    变量定义和声明的差别(整理)
    浏览器内核分类
    设计模式 之 享元
    FPGA中浮点运算实现方法——定标
    兔子--Android中的五大布局
  • 原文地址:https://www.cnblogs.com/ddlove/p/6280228.html
Copyright © 2020-2023  润新知