JavaScript Touch事件详解:原理、属性与移动端最佳实践

作者:白露时间:2026-10-29 15:03:39浏览:310

本文深入解析JavaScript中的Touch事件机制,涵盖touchstart、touchmove、touchend等核心事件的触发时机与区别。详细阐述Touch对象属性(如clientX、identifier)及事件列表(touches、targetTouches)的用法。结合代码示例,介绍拖拽、多点触控等交互实现,并提供禁用缩放、优化渲染性能等移动端开发最佳实践,帮助开发者构建流畅的触屏应用。

JavaScript Touch事件概述

JavaScript中的Touch事件主要应用于移动设备的触屏滑动交互场景。

相关代码示例如下:

$(function(){document.addEventListener("touchmove", _touch, false);}) function _touch(event){alert(1;}

Touch事件类型与属性详解

Touch事件包含四种主要类型:touchstart表示手指接触屏幕时触发,即使屏幕上已有其他手指放置也会触发;touchmove表示手指在屏幕上滑动时连续触发,期间调用preventDefault()可阻止页面滚动;touchend表示手指从屏幕移开时触发;touchcancel表示系统停止跟踪触摸时触发,具体触发条件文档中未明确说明。

上述事件的事件对象(event)包含以下公共属性:

touches:当前跟踪的所有触摸操作的Touch对象数组;targetTouches:特定于事件目标的Touch对象数组;changeTouches:表示自上次触摸以来发生变化的Touch对象数组。

每个Touch对象包含以下具体属性:

clientX:触摸点在视口中的X坐标;clientY:触摸点在视口中的Y坐标;identifier:触摸的唯一ID;pageX:触摸点在页面中的X坐标;pageY:触摸点在页面中的Y坐标;screenX:触摸点在屏幕中的X坐标;screenY:触摸点在屏幕中的Y坐标;target:触摸所针对的DOM节点。

基本触摸事件与列表机制

触摸事件分类

规范中列出并获得跨移动设备广泛实现的三种基本触摸事件为:1. touchstart:手指放置在一个DOM元素上时触发;2. touchmove:手指拖曳一个DOM元素时触发;3. touchend:手指从一个DOM元素上移开时触发。

每个触摸事件包含三个触摸列表:1. touches:当前位于屏幕上的所有手指列表;2. targetTouches:位于当前DOM元素上的手指列表;3. changedTouches:涉及当前事件的手指列表。

例如,在touchend事件中,changedTouches包含的是移开的那根手指。

这些列表由包含触摸信息的对象组成:1. identifier:唯一标识当前手指的数值;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硬件上测试了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次,所有被测试设备均如此。

作者最新文章