Hammer.js移动端手势库入门指南:六大事件详解与实战
本文介绍轻量级移动端脚本框架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事件进行监听。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持本站。
D3.js 处理大规模数据点的性能优化策略
2026-11-05 15:37:25
JS实现网页摄像头实时扫码:结合getUserMedia与jsQR教程
2026-11-05 15:27:28
D3.js v5 迁移到 v7 的 API 变更与注意事项
2026-11-05 11:57:17
使用 animate.js 实现多元素协同的序列动画
2026-11-04 22:27:53
JS拖拽排序时怎么添加平滑动画效果?FLIP技术实战
2026-11-04 10:12:22
