Hammer.js移动端手势库入门指南:六大事件详解与实战

作者:像素漫游时间:2026-10-21 18:07:25浏览:449

本文介绍轻量级移动端脚本框架Hammer.js,基于v2.0.4版本。详解Pan、Pinch、Press、Rotate、Swipe、Tap六大手势事件及子事件监听。通过对比Click事件在安卓端的延迟问题,阐述使用Tap优化的必要性,并提供各事件代码示例与注意事项。

前言

一、前言

当前移动端开发框架虽处于初级阶段,但已历经较长时间的发展。尽管PC端开发的需求量依然较大,但移动Web的发展已成为必然趋势。在接触移动端脚本时,最初考虑的是jQuery。jQuery 2.0及以上版本开始侧重移动端支持,例如对HTML5的支持,但完善程度仍有待提高,期待后续版本能进一步改善。

早期开发移动Web时,通常采用W3C标准语法结合原生JavaScript进行开发。这种方式开发工作量较大,且需逐一处理各移动端浏览器的兼容性问题。例如Windows Phone(WP)手机常向W3C申请独立标准,导致兼容处理尤为棘手。因此,构建一个良好的兼容性架构能显著减少开发者的工作量。

在接触移动端框架初期,咨询了一些从事前端开发的朋友,他们大多就职于百度、阿里等公司。参考建议后,项目初期使用了zepto.js(许多前端开发者对此并不陌生)。然而,该框架存在一个显著缺陷:不兼容WP手机。在使用zepto.js完成项目后,再针对WP手机进行兼容调整,往往显得“得不偿失”。后续咨询发现,许多公司在开发时已基本放弃对WP的兼容支持。随后了解到有人使用hammer.js进行开发,经研究,发现hammer.js具有轻量级、封装良好、使用便捷及兼容性优良等特点。鉴于网上中文资料较少,专门撰写此文以作分享。

本文基于hammer.js官网:http://hammerjs.github.io/,版本依据为v2.0.4。若文中API已过期,请自行访问官网查询最新文档。本文仅作为入门参考。

Hammer.js简介

二、hammer.js是什么

hammer.js是一款开源的移动端脚本框架,能够完美实现移动端开发中的大多数事件,如点击、滑动、拖动、多点触控等。该框架不依赖任何其他库,整体体积非常小,使用时十分简便。代码示例如下:


<div id="test" class="test"></div> 
  <script type="text/javascript"> 
    //创建一个新的hammer对象并且在初始化时指定要处理的dom元素 
    var hammertime = new Hammer(document.getElementById("test")); 
    //为该dom元素指定触屏移动事件 
    hammertime.on("pan", function (ev) { 
     //控制台输出 
     console.log(ev); 
    }); 
</script> 

事件架构详解

三、事件架构

hammer.js主要针对触屏的6大事件进行监听。如下图所示:

前言

1、Pan事件:在指定的DOM区域内,一个手指放下并移动的事件,即触屏中的拖动事件。该事件在触屏开发中较为常用,例如左拖动、右拖动等,如手机QQ向右滑动出现功能菜单的效果。该事件还可分别监听并处理以下子事件:Panstart(拖动开始)、Panmove(拖动过程)、Panend(拖动结束)、Pancancel(拖动取消)、Panleft(向左拖动)、Panright(向右拖动)、Panup(向上拖动)、Pandown(向下拖动)。

2、Pinch事件:在指定的DOM区域内,两个手指(默认为两个手指,多指触控需单独设置)或多个手指相对(越来越近)移动或相向(越来越远)移动时触发的事件。该事件可分别监听并处理以下子事件:Pinchstart(多点触控开始)、Pinchmove(多点触控过程)、Pinchend(多点触控结束)、Pinchcancel(多点触控取消)、Pinchin(两手指距离越来越近)、Pinchout(两手指距离越来越远)。

3、Press事件:在指定的DOM区域内,触屏版本的点击事件,相当于PC端的Click事件。该事件不能包含任何移动,最小按压时间为500毫秒,常用于手机上的“复制、粘贴”等功能。该事件可监听并处理以下子事件:Pressup(点击事件离开时触发)。

4、Rotate事件:在指定的DOM区域内,当两个手指或更多手指成圆形旋转时触发(类似拧螺丝的动作)。该事件可分别监听并处理以下子事件:Rotatestart(旋转开始)、Rotatemove(旋转过程)、Rotateend(旋转结束)、Rotatecancel(旋转取消)。

5、Swipe事件:在指定的DOM区域内,一个手指快速在触屏上滑动。即我们平时用到最多的滑动事件。包括:Swipeleft(向左滑动)、Swiperight(向右滑动)、Swipeup(向上滑动)、Swipedown(向下滑动)。

6、Tap事件:在指定的DOM区域内,一个手指轻拍或点击时触发该事件(类似PC端的Click)。该事件最大点击时间为250毫秒,如果超过250毫秒则按Press事件进行处理。

经验分享:在编写此事件时,有人可能会问,在触屏中使用Click事件不也可以吗?Tap事件与Click事件有何区别?博主也曾有此疑惑,起初在触屏上处理点击时一直使用Click事件,且未出现问题。直到为某公司开发微信版本的“连连看”小游戏时,问题显现。游戏逻辑为点击两个相同图案图片时,中间产生连接线并爆破消失。初期在Firefox浏览器上测试,鼠标点击效果流畅;部署到服务器并在手机端操作时,iPhone和WP运行流畅,但安卓设备无论怎样调整均有卡顿。起初怀疑手机性能问题,更换高配手机后仍卡顿,游戏虽可玩但反应缓慢。经多次测试排除硬件原因后,怀疑Click事件。查阅资料得知,在安卓触屏上,Tap事件和Click事件可同时触发,但Click事件会有几百毫秒的延迟,即先触发Tap事件,过一段时间再触发Click事件。随后将游戏所有Click事件修改为Tap事件,问题自然解决。

使用实例与代码示例

四、 使用实例

1、 Pan

代码如下


 <!DOCTYPE html> 
 <html> 
 <head> 
   <meta name="viewport" content="width=device-width" /> 
   <title>Pan</title> 
   <script src="/Script/hammer.js"></script> 
   <style type="text/css"> 
     html, body { 
       width: 100%; 
       height: 100%; 
       margin: 0px; 
       padding: 0px; 
     } 
  
     .test { 
       width: 100%; 
      height: 50%; 
      background: #ffd800; 
       text-align: left; 
     } 
  
    .result { 
       width: 100%; 
       height: 50%; 
       background: #b6ff00; 
       text-align: left; 
     } 
   </style> 
 </head> 
 <body> 
   <div id="test" class="test">事件区域</div> 
   <div id="result" class="result">事件结果<br /></div> 
   <script type="text/javascript"> 
     //创建一个新的hammer对象并且在初始化时指定要处理的dom元素 
    var hammertime = new Hammer(document.getElementById("test")); 
     //添加事件 
    hammertime.on("pan", function (e) { 
       document.getElementById("result").innerHTML += "X偏移量:【" + e.deltaX + "】,Y偏移量:【" + e.deltaY + "】<br />"; 
       //控制台输出 
      console.log(e); 
     }); 
  </script> 
 </body> 
 </html> 

效果如下:

  前言

2、Pinch

代码如下:


 <!DOCTYPE html> 
<html> 
 <head> 
   <meta name="viewport" content="width=device-width" /> 
 <title>Pinch</title> 
  <script src="/Script/hammer.js"></script> 
  <style type="text/css"> 
     html, body { 
      width: 100%; 
      height: 100%; 
      margin: 0px; 
      padding: 0px; 
    } 
    .test { 
      width: 100%; 
      height: 50%; 
      background: #ffd800; 
      text-align: left; 
    } 
    .result { 
      width: 100%; 
      height: 50%; 
      background: #b6ff00; 
      text-align: left; 
    } 
  </style> 
</head> 
<body> 
  <div id="test" class="test">事件区域</div> 
  <div id="result" class="result">事件结果:捏合触发<br /></div> 
  <script type="text/javascript"> 
    //创建一个新的hammer对象并且在初始化时指定要处理的dom元素 
    var hammertime = new Hammer(document.getElementById("test")); 
    //为该dom元素指定触屏移动事件 
    hammertime.add(new Hammer.Pinch()); 
    //添加事件 
    hammertime.on("pinchin", function (e) { 
      document.getElementById("result").innerHTML += "捏合初触发<br />"; 
      //控制台输出 
      console.log(e); 
    }); 
  </script> 
</body> 
</html> 

效果如下:

 前言

3、Press

代码如下:


 <!DOCTYPE html> 
 <html> 
 <head> 
  <meta name="viewport" content="width=device-width" /> 
  <title>Press</title> 
   <script src="/Script/hammer.js"></script> 
   <style type="text/css"> 
    html, body { 
      width: 100%; 
       height: 100%; 
       margin: 0px; 
       padding: 0px; 
     } 
  
     .test { 
       width: 100%; 
      height: 50%; 
       background: #ffd800; 
       text-align: left; 
    } 
    .result { 
       width: 100%; 
       height: 50%; 
      background: #b6ff00; 
       text-align: left; 
     } 
   </style> 
 </head> 
 <body> 
   <div id="test" class="test">事件区域</div> 
   <div id="result" class="result">事件结果:按压超过500ms触发<br /></div> 
  <script type="text/javascript"> 
     //创建一个新的hammer对象并且在初始化时指定要处理的dom元素 
     var hammertime = new Hammer(document.getElementById("test")); 
    //添加事件 
    hammertime.on("press", function (e) { 
      document.getElementById("result").innerHTML += "超过500ms了<br />"; 
      //控制台输出 
      console.log(e); 
     }); 
   </script> 
</body> 
</html> 

效果如下:

 前言

4、Rotate

代码如下:


 <!DOCTYPE html> 
 <html> 
<head> 
  <meta name="viewport" content="width=device-width" /> 
  <title>Rotate</title> 
  <script src="/Script/hammer.js"></script> 
  <style type="text/css"> 
    html, body { 
      width: 100%; 
      height: 100%; 
      margin: 0px; 
       padding: 0px; 
    } 
    .test { 
      width: 100%; 
       height: 50%; 
      background: #ffd800; 
       text-align: left; 
     } 
     .result { 
       width: 100%; 
       height: 50%; 
      background: #b6ff00; 
       text-align: left; 
     } 
  </style> 
 </head> 
 <body> 
  <div id="test" class="test">事件区域</div> 
<div id="result" class="result">事件结果:旋转触发<br /></div> 
  <script type="text/javascript"> 
    //创建一个新的hammer对象并且在初始化时指定要处理的dom元素 
     var hammertime = new Hammer(document.getElementById("test")); 
     //为该dom元素指定触屏移动事件 
    hammertime.add(new Hammer.Rotate()); 
     //添加事件 
    hammertime.on("rotate", function (e) { 
       document.getElementById("result").innerHTML += "X偏移量:【" + e.deltaX + "】,Y偏移量:【" + e.deltaY + "】<br />"; 
       //控制台输出 
       console.log(e); 
     }); 
   </script> 
 </body> 
 </html> 

效果如下:

 前言

5、Swipe

代码如下:


<!DOCTYPE html> 
<html> 
 <head> 
  <meta name="viewport" content="width=device-width" /> 
  <title>Swipe</title> 
  <script src="/Script/hammer.js"></script> 
  <style type="text/css"> 
    html, body { 
      width: 100%; 
       height: 100%; 
      margin: 0px; 
      padding: 0px; 
     } 
    .test { 
       width: 100%; 
      height: 50%; 
      background: #ffd800; 
       text-align: left; 
    } 
    .result { 
       width: 100%; 
      height: 50%; 
       background: #b6ff00; 
       text-align: left; 
    } 
  </style> 
 </head> 
 <body> 
   <div id="test" class="test">事件区域</div> 
  <div id="result" class="result">事件结果:向左滑动触发<br /></div> 
   <script type="text/javascript"> 
    //创建一个新的hammer对象并且在初始化时指定要处理的dom元素 
     var hammertime = new Hammer(document.getElementById("test")); 
    //添加事件 
    hammertime.on("swipeleft", function (e) { 
      document.getElementById("result").innerHTML += "X偏移量:【" + e.deltaX + "】,Y偏移量:【" + e.deltaY + "】<br />"; 
       //控制台输出 
       console.log(e); 
     }); 
  </script> 
 </body> 
</html> 

效果如下:

 前言

6、Tab

代码如下:


<!DOCTYPE html> 
 <html> 
 <head> 
  <meta name="viewport" content="width=device-width" /> 
  <title>Tap</title> 
  <script src="/Script/hammer.js"></script> 
  <style type="text/css"> 
    html, body { 
       width: 100%; 
       height: 100%; 
       margin: 0px; 
      padding: 0px; 
     } 
    .test { 
       width: 100%; 
      height: 50%; 
       background: #ffd800; 
      text-align: left; 
     } 
    .result { 
       width: 100%; 
      height: 50%; 
      background: #b6ff00; 
      text-align: left; 
    } 
  </style> 
 </head> 
 <body> 
   <div id="test" class="test">事件区域</div> 
   <div id="result" class="result">事件结果:点击触发<br /></div> 
   <script type="text/javascript"> 
     //创建一个新的hammer对象并且在初始化时指定要处理的dom元素 
     var hammertime = new Hammer(document.getElementById("test")); 
    //添加事件 
     hammertime.on("tap", function (e) { 
      document.getElementById("result").innerHTML += "点击触发了,长按无效<br />"; 
       //控制台输出 
      console.log(e); 
     }); 
  </script> 
 </body> 
 </html> 

效果如下:

 前言

上述实例存在差异。在Pinch事件和Rotate事件中,使用了hammertime.add(new Hammer.Pinch())和hammertime.add(new Hammer.Rotate());而其他四个事件未使用,而是直接添加事件监听程序。原因在于,在new Hammer(htmlElement)时,Hammer.js默认对Pan、Press、Swipe和Tap事件进行了监听,但未对Pinch和Rotate事件进行监听。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。

作者最新文章