移动端事件基础介绍
前面我们已经了解了移动端的适配以及响应式布局相关知识,从这一章开始,我们就要进入到移动端另外一个非常重要的章节“移动端事件”了。
本文将介绍以下内容:
- 移动端有哪些事件
- 事件对象
- 移动端事件和 PC 端事件区别
- 事件穿透
- 阻止默认行为带来的影响
移动端有哪些事件
在学习 PC 端的时候,我们已经接触过事件了,而到了移动端,又有了新的事件,分别为:
- touchstart:手指按下事件,类似 mousedown
- touchmove:手指移动事件,类似 mousemove
- touchend 手指抬起事件,类似 mouseup
例如:
<div class="container"></div>
* {
margin: 0;
padding: 0;
}
.container {
width: 200px;
height: 200px;
background-color: red;
}
var box = document.querySelector('.container');
box.addEventListener('touchstart', () => {
console.log('手指按下去了');
});
box.addEventListener('touchmove', () => {
console.log('手指滑动了');
});
box.addEventListener('touchend', () => {
console.log('手指抬起了');
});
事件对象
之前在学习事件的时候,有一个非常重要的东西,那就是事件对象。通过事件对象,我们可以获取到本次事件发生时,一些更加具体的信息。上面所介绍的移动端事件,自然也是有事件对象传入回调函数的。例如:
box.addEventListener('touchstart', (e) => {
console.log(e);
});
此时我们打印传入的事件对象,可以看到如下的信息:

可以看到,事件对象中一如既往的包含了很多信息,其中对于我们开发来讲比较重要的就是如下 3 个信息:
changedTouches、targetTouches、touches 这 3 个对应的值都是 TouchList(手指列表)
- changedTouches:触发当前事件的手指列表,也就是涉及当前(引发)事件的触摸点的列表
- targetTouches:位于当前 DOM 元素上的手指列表,也就是当前对象上所有触摸点的列表
- touches:位于当前屏幕上的所有手指列表(必需至少有 1 个手指在添加触发事件的元素上),也就是当前屏幕上所有触摸点的列表
通过一个例子来区分一下触摸事件中的这三个属性:
比如 div1、div2 只有 div2 绑定了 touchstart 事件,第一次放下一个手指在 div2 上,触发了 touchstart 事件,这个时候,三个集合的内容是一样的,都包含这个手指的 touch,然后,再放下两个手指一个在 div1 上,一个在 div2 上,这个时候又会触发事件,但 changedTouches 里面只包含第二个第三个手指的信息,因为第一个没有发生变化,而 targetTouches 包含的是在第一个手指和第三个在 div2 上的手指集合,touches 包含屏幕上所有手指的信息,也就是三个手指。
网上有个灵魂画手对此做了一个绘制:

移动端事件和 PC 端事件区别
虽说有了移动端专属的事件,并不意味着原本 PC 端的浏览器事件就不能用了,但是还是推荐尽量使用移动端的专属事件,因为 PC 端的事件并不是专门为移动端设计的,因此会存在各种各样的问题,其中一个比较出名的就是移动端 300ms 延迟。
为什么移动端点击事件要加 300ms 延迟呢?
早在 2007 年初,苹果公司在发布首款 iPhone 前夕,遇到一个问题:当时的网站都是为大屏幕设备所设计的。于是苹果的工程师们做了一些约定,应对 iPhone 这种小屏幕浏览桌面端站点的问题。
这当中最出名的,当属双击缩放( double tap to zoom ),这也是会有上述 300 毫秒延迟的主要原因。
双击缩放,顾名思义,即用手指在屏幕上快速点击两次,iOS 自带的 Safari 浏览器会将网页缩放至原始比例。 那么这和 300 毫秒延迟有什么联系呢?
假定这么一个场景: 用户在 iOS Safari 里边点击了一个链接。由于用户可以进行双击缩放或者双击滚动的操作,当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击操作。因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕。
鉴于 iPhone 的成功,其他移动浏览器都复制了 iPhone Safari 浏览器的多数约定,包括双击缩放,几乎现在所有的移动端浏览器都有这个功能。
下面我们能够来看一下这个问题
var box = document.querySelector('.container');
box.addEventListener('click', () => {
console.log('click 事件触发');
});
box.addEventListener('touchstart', () => {
console.log('touchstart 事件触发');
});
在 2014 年,从 Chrome32 开始 Google 已经解决这个 300ms 延迟问题,只要定义了 viewport 就不会有 300ms 延迟问题。
除此之外,我们来看一下移动端事件和 PC 端事件之间的其他区别。虽然上面介绍的 3 个移动端事件,都能找到其在 PC 端中相似的事件,但是仔细一比较,也是存在如下区别的:
- 触发点区别
- 触发顺序的区别
- touchstart 与 click 的区别
触发点区别
PC 端
-
mousemove:不需要鼠标按下,但是必需在元素上才能触发
-
mouseup:必需在元素上抬起才能触发
移动端
-
touchmove:必需手指按下才能触发,但是,按下后不在元素上也能触发
-
touchend:不需要在元素上抬起就能触发
触发顺序
触发顺序依次为:touchstart → touchend → mousedown → click → mouseup
并且 PC 的事件在移动端里会有 300ms左右 延迟
touchstart 与 click 的区别
touchstart 为手指碰到元素就触发,click 为手指碰到元素并且抬起才会触发
事件穿透
所谓事件穿透,是移动端上面一个非常有名的 Bug,其出现场景为:有两层重叠的元素,上面的元素有 touch 事件(点击后要消失),下面是一个默认会触发 click 事件的元素(a、表单元素、带 click 事件的元素),此时点击上一层的元素,下一层也同样会被点击。
来看一个例子:
<a href="http://www.baidu.com/">度娘</a><br>
<input type="text">
<p>这是一个段落</p>
<div class="container"></div>
* {
margin: 0;
padding: 0;
}
.container {
width: 200px;
height: 200px;
background: green;
color: #fff;
position: absolute;
left: 0;
top: 0;
opacity: 0.5;
}
input {
border: 1px solid #000;
}
var box = document.querySelector('.container');
box.addEventListener('touchstart', () => {
box.style.display = 'none';
});
const p = document.querySelector('p');
p.addEventListener('click', () => {
alert('该段落被点击了');
});
为什么会存在事件穿透呢?
这是因为在移动端浏览器,事件执行的顺序是 touchstart → touchmove → touched → click。而 click 事件有 300ms 的延迟,当 touchstart 事件把上层元素隐藏之后,隔了 300ms,浏览器触发了 click 事件,但是此时上层元素不见了,所以该事件被派发到了下层元素身上。
那么既然存在这个问题,该如何解决呢?
有一个最简单的解决方式,那就是取消事件的默认行为,如下:
box.addEventListener('touchstart', ev => {
box.style.display = 'none';
ev.preventDefault(); // 取消事件的默认动作
});
当我们阻止了 touchstart 事件的默认行为后,事件穿透也就随即消失。
阻止默认行为带来的影响
在上面,我们虽然使用事件对象的 preventDefault 方法来阻止元素的默认行为。
在移动端,不仅元素身上绑定了默认事件,在 document 身上也绑定了默认事件,因此我们可以利用冒泡事件来阻止默认事件,也就是说哪怕你元素本身没有阻止默认事件,你触发了默认事件,但是通过冒泡父元素身上取消了默认事件,那么最终的结果默认事件也会被取消掉,因为根据事件流,元素身上的事件在目标阶段触发,冒泡事件在冒泡阶段触发,冒泡阶段在目标阶段之后,最终结果取决于后执行的事件。利用这个思想我们就可以通过在 document 身上取消默认事件,从而阻止所有的默认事件。
虽然我们阻止掉了所有的默认事件,但是这种方法也带来了新的问题:
touchmove
-
阻止了浏览器的滚动条
-
阻止了用户双指缩放
touchstart
- 解决 IOS10+ 及部分安卓机通过设置 viewport 禁止用户缩放的功能(双指滑动、双击)
- 解决事件点透问题
- 阻止图片文字被选中
- 阻止了长按元素会弹出系统菜单
- 阻止了浏览器回弹的效果
- 阻止了浏览器的滚动条
- 阻止了鼠标的事件
- 阻止了 input 框的输入功能
我们可以通过下面的例子来看到部分功能已经失效。
<div class="page">
<img src="./ok.png" alt="" width="100%">
<input type="text">
<ul>
<li><a href="http://www.baidu.com">度娘</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
<li><a href="#">这是一个很长很长的链接</a></li>
</ul>
</div>
body {
margin: 0;
}
ul {
margin: 0;
padding: 0;
list-style: none;
}
li {
line-height: 50px;
}
li a {
font-size: 30px;
}
input {
border: 1px solid #000;
}
const page = document.querySelector('.page');
page.addEventListener('touchstart', ev => {
ev.preventDefault();
});
另外,如果是在 document 上面阻止默认事件,例如将上面的 JavaScript 修改如下:
document.addEventListener('touchstart',ev=>{ ev.preventDefault(); });会发现在 chrome 移动端模拟器或者手机浏览器上事件的默认行为并没有成功阻止。其中 preventDefault 不生效问题就是由 passive 这个参数引起的。
tartget.addEventListener(type, listener, { capture: Booolean, once: Boolean, passive: Boolean, signal: AbortSignal })为什么呢?
事件监听器在监听事件时,并不能提前知道回调函数中是否会阻止默认行为,因此若想知道是否会阻止就需要等待函数执行完,这段时间虽然很短,但等待仍会让人感到卡顿。
于是我们可以通过传递 passive 为 true 来明确告诉浏览器,事件处理程序不会调用 preventDefault 来阻止默认滑动行为。而大部分事件监听器是不会阻止默认行为的,因此某些浏览器就将一些节点(例如 document)事件的 passive 默认设置为为 true。
因此要解决上面 document 上无法阻止默认行为的情况,只需要将 passive 设置为 false 即可。即明确告诉浏览器,事件处理程序会调用 preventDefault 来阻止默认滑动行为。
document.addEventListener('touchstart', ev => { ev.preventDefault(); }, { passive: false });
回到之前的话题,在父元素上面阻止元素默认行为,会导致很多元素的默认行为也没有了,那么此时该怎么办呢?
比如在获取验证码时,验证码通常用户希望是能够复制的,因此会触发长按复制的默认事件,这个事件我们希望在这个元素身上不被阻止掉,那么应该如何实现?
有一种方案是阻止冒泡。如上面所述,我们是通过冒泡来借助父元素阻止掉默认事件,那么如果我们切断冒泡,那么父元素身上的阻止默认事件就无法被触发,元素本身的默认事件就无法被阻止掉了。
但是这样也只是解决了其中一个问题,上面还罗列出了很多其他问题,例如所有的滚动条失效,这些问题该怎么解决呢?
实际上,移动端进行开发时一上来就需要阻止所有的默认事件,后面的很多功能都需要我们自定义来实现。
2. 滑屏操作与轮播图
在上一讲中,我们介绍了移动端事件的一些基本知识,也知道了移动端中如果在 document 上面阻止了默认事件的话,又会出现很多新的问题,例如 a 标签无法跳转,表单输入控件无法选中。这些问题都需要我们自己来解决。
例如:a 标签无法跳转
dom.addEventListener('touchstart',e=>{
location.href = e.target.href;
})
表单输入控件无法选中
input.addEventListener('touchstart',ev=>{
input.focus();
})
这些问题我们倒还是能够很轻松的解决。
但是其中有一条是连基本的滑动都会被阻止掉了,因此同样,滑屏也只有通过我们自己手动实现。
本小节我们来看一个移动端中常见的操作:滑屏。并且在此基础上来实现一个轮播图。
本文主要介绍以下内容:
- 滑屏操作
- 轮播图
滑屏操作
还记得上一小节中我们所说的,在移动端中我们要阻止所有的默认事件,这样就能解决一些诸如事件穿透的 Bug。但是这随之而来的带给我们一些新的问题:那就是阻止了默认行为之后,很多东西都失效了,例如滚动条失效,因此,很多功能都需要我们自定义来实现。
这里我们就来实现一个滑屏操作。
实际上,滑屏操作的原理并不难理解,就和以前在 PC 端所书写的拖动是一样的。
首先我们复习一下事件对象中的 changedTouches 属性,该属性可以获取当前(引发)事件的触摸点的列表。列表的每一项为一个 Touch 对象,里面有那么一些属性,如下:
关于 Touch 对象各属性的含义,可以参阅 MDN:developer.mozilla.org/zh-CN/docs/…
下面是一段滑屏操作的示例代码:
<div id="wrap">
<ul id="list">
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表10</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表1</a></li>
<li><a href="#">这是一个很长很长的列表20</a></li>
</ul>
</div>
body{
margin: 0;
}
ul{
margin: 0;
padding: 0;
list-style: none;
}
#wrap{
height: 100vh;
overflow: hidden;
border: 5px solid #f00;
box-sizing: border-box;
}
#list{
transition: 0.3s;
}
#list li{
font-size: 24px;
line-height: 50px;
}
var wrap=document.querySelector('#wrap'),
list=document.querySelector('#list');
var startPointY=0, //按下时手指的坐标
startTop=0, //按下时元素的距离
movePointY=0; //手指移动时的坐标
Transform(list); //使用第三方的库,在一上来的时候设置一下初始的距离
wrap.addEventListener('touchstart',ev=>{
startPointY=ev.changedTouches[0].pageY; //按下的时候获取手指的坐标
startTop=list.translateY;
});
wrap.addEventListener('touchmove',ev=>{
//坐标移动的距离 = 当前的距离-按下时的距离
movePointY=ev.changedTouches[0].pageY-startPointY;
//元素走的距离=按下时元素的距离+坐标移动的距离
list.translateY=startTop+movePointY;
ev.preventDefault();
});
因为滑屏操作涉及到频繁的滑动,而以前传统的通过 position 的方式来实现的话,会有重绘重排的性能问题,因此我们选择使用 CSS3 的 transform 来实现滑动效果,CSS3 新增的 transform 有硬件加速等特性,性能上面要比传统的 position 要好一些。
另外,在上面的代码中,我们用到了一个第三方库 Transform:github.com/AlloyTeam/P…
轮播图
接下来我们在滑屏操作上更进一步,来实现一个轮播图。
其原理如下图所示:

代码如下:
<section id="banner">
<div class="wrap">
<a href="#"><img src="images/banner_01.jpg" alt=""></a>
<a href="#"><img src="images/banner_02.jpg" alt=""></a>
<a href="#"><img src="images/banner_03.jpg" alt=""></a>
</div>
<div class="circle">
<span class="active"></span><span></span><span></span>
</div>
</section>
body {
margin: 0;
}
#banner {
position: relative;
width: 100vw;
overflow: hidden;
}
.wrap {
width: 300vw;
display: flex;
}
.wrap a {
width: 100vw;
}
.wrap a img {
width: 100%;
vertical-align: middle;
}
.circle {
position: absolute;
bottom: 3vw;
width: 100vw;
display: flex;
justify-content: center;
}
.circle span {
width: 3vw;
height: 3vw;
background: #ddd;
border-radius: 50%;
margin: 0 1.5vw;
}
.circle span.active {
background: grey;
opacity: .8;
}
var banner = document.querySelector('#banner'),
wrap = document.querySelector('.wrap'),
spans = document.querySelectorAll('.circle span'),
imgWidth = banner.offsetWidth; // 一张图片的宽度
var startPointX = 0, // 按下时手指的坐标
disPointX = 0, // 手指坐标的差
startEleX = 0, // 按下时元素的位置
cn = 0, // 当前图片走的索引数
ln = 0; // 上一个图片走的索引
Transform(wrap);
//无缝滚动
wrap.innerHTML += wrap.innerHTML; //复制了一份
wrap.style.width = wrap.children.length * imgWidth + 'px';
banner.addEventListener('touchstart', ev => {
startPointX = ev.changedTouches[0].pageX;
// 按下的是第 0 张图,要做的事情:让 wrap 走到第 2 份的第 0 张,左边就有内容
if (cn == 0) {
cn = wrap.children.length / 2;
}
// 按下的是最后一张图,要做的事情:让 wrap 走到第 1 份的最后一张图
if (cn == wrap.children.length - 1) {
cn = wrap.children.length / 2 - 1;
}
wrap.style.transition = ''; // 不去掉的放在拖动的时候会很慢
// 当改变了 cn 的值后也需要修正一下 wrap 的位置, 使其马上变过去,以免两边出现留白
wrap.translateX = -imgWidth * cn;
startEleX = wrap.translateX; // 当 wrap 的位置改变后,需要去更新一下初始值(元素的位置)
ev.preventDefault();
});
banner.addEventListener('touchmove', ev => {
disPointX = ev.changedTouches[0].pageX - startPointX;
wrap.translateX = startEleX + disPointX;
});
banner.addEventListener('touchend', ev => {
// 回弹的效果
var backWidth = imgWidth / 8; //加弹的距离,超过这个距离才能运动到下一张,小于这个距离就需要回弹
if (Math.abs(disPointX) > backWidth) {
// 这个条件满足了说明现拖动的距离已经超过回弹的距离了,可以运动到下一张了
// 判断现在是往右边拖还是往左边拖
if (disPointX < 0) {
// 往左边拖
cn++;
}
if (disPointX > 0) {
// 往右边拖
cn--;
}
}
wrap.style.transition = '0.3s';
wrap.translateX = -imgWidth * cn;
//修改小圆点的class
/*
现在图片的索引:0,1,2,3,4,5 => 0,1,2,0,1,2
span标签的索引:0,1,2
*/
// 先去掉上一个次圆点身上的class
spans[ln].className = '';
// 先去掉上一个次圆点身上的class
spans[cn % (wrap.children.length / 2)].className = 'active';
// 再最后的时候需要去更新一下上一个的索引,更新为这次。相对于下次来说,它的上一次是不是就是当前次
ln = cn % (wrap.children.length / 2);
});
移动端第三方库
在做 PC 端的开发时,我们往往会用到第三方库,这样可以大大的提升我们的开发效率。
而在做移动端页面时,同样存在非常好用的第三方库,本小节我们就一起来看两个在移动端开发中非常有名的第三方库:
- Swiper.js 轮播图库
- 移动端手势库
Swiper.js 轮播图库
在上一节课中,我们实现了移动端中常见的滑屏和轮播图。
有一些比较成熟的库,可以提升我们的开发效率。这里首先要介绍的第一个库就是来自我们国人开发的 Swiper.js。
官网地址:www.swiper.com.cn/
这是一个非常方便的制作轮播图的的第三方库,支持各种姿势的轮播,很多大厂也是在自己的移动端网页中使用这个库。

移动端手势库
Hammer.js 是一款开源的移动端第三方库,Hammer.js 不需要依赖任何其他的 JS 框架或者库,并且整个框架非常小,v2.0.4 版本只有 3.96kb。
Hammer.js 官网地址:hammerjs.github.io/
Hammer.js 可以完美的实现在移端开发的大多数事件,如:点击、滑动、拖动、多点触控等事件。
Hammer.js 在使用时非常简单,示例如下:
<div id="test" class="test"></div>
//创建一个新的hammer对象并且在初始化时指定要处理的dom元素
var hammertime = new Hammer(document.getElementById("test"));
//为该dom元素指定触屏移动事件
hammertime.on("pan", function (ev) {
//控制台输出
console.log(ev);
});
Hammer.js 主要事件如下:

Rotate 事件
在指定的 dom 区域内,当两个手指或更多手指成圆型旋转时触发(就像两个手指拧螺丝一样)。
- Rotate:所有旋转的集合
- Rotatestart:旋转开始
- Rotatemove:旋转过程
- Rotateend:旋转结束
- Rotatecancel:旋转取消
<div id="test" class="test">事件区域</div>
<div id="result" class="result">事件结果:旋转触发<br /></div>
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;
}
// 创建一个新的 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);
});
Pinch 事件
在指定的 dom 区域内,两个手指(默认为两个手指,多指触控需要单独设置)或多个手指相对(越来越近)移动或相向(越来越远)移动时事件。除了 Pinch 事件以外,该事件事以分别对以下事件进行监听并处理:
- Pinchstart:多点触控开始
- Pinchmove:多点触控过程
- Pinchend:多点触控结束
- Pinchcancel:多点触控取消
- Pinchin:多点触控时两手指距离越来越近
- Pinchout:多点触控时两手指距离越来越远
<div id="test" class="test">事件区域</div>
<div id="result" class="result">事件结果:捏合触发<br /></div>
// 创建一个新的 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);
});
Press 事件
在指定的 dom 区域内触屏版本的点击事件,这个事件相当于 PC 端的 Click 事件,该不能包含任何的移动,最小按压时间为 500 毫秒,常用于我们在手机上用的“复制、粘贴”等功能。
- Press:按压后触发
- Pressup:按压离开时触发
<div id="test" class="test">事件区域</div>
<div id="result" class="result">事件结果:按压超过500ms触发<br /></div>
//创建一个新的hammer对象并且在初始化时指定要处理的dom元素
var hammertime = new Hammer(document.getElementById("test"));
//添加事件
hammertime.on("press", function (e) {
document.getElementById("result").innerHTML += "超过500ms了<br />";
//控制台输出
console.log(e);
});
Pan 事件
在指定的 dom 区域内,一个手指放下并移动事件,即触屏中的拖动事件。这个事件在屏触开发中比较常用,如:左拖动、右拖动等,如手要上使用 QQ 时向右滑动出现功能菜单的效果。除了 Pan 事件以外,该事件还可以分别对以下事件进行监听并处理:
- Panstart:拖动开始
- Panmove:拖动过程
- Panend:拖动结束
- Pancancel:拖动取消
- Panleft:向左拖动
- Panright:向右拖动
- Panup:向上拖动
- Pandown:向下拖动
使用示例如下:
<div id="test" class="test">事件区域</div>
<div id="result" class="result">事件结果<br /></div>
//创建一个新的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);
});
Tap 事件
在指定的 dom 区域内,一个手指轻拍或点击时触发该事件(类似 PC 端的 click)。该事件最大点击时间为 250 毫秒,如果超过 250 毫秒则按 Press 事件进行处理。
<div id="test" class="test">事件区域</div>
<div id="result" class="result">事件结果:点击触发<br /></div>
//创建一个新的hammer对象并且在初始化时指定要处理的dom元素
var hammertime = new Hammer(document.getElementById("test"));
//添加事件
hammertime.on("tap", function (e) {
document.getElementById("result").innerHTML += "点击触发了,长按无效<br />";
//控制台输出
console.log(e);
});
Swipe 事件
在指定的 dom 区域内,一个手指快速的在触屏上滑动。即我们平时用到最多的滑动事件。
- Swipe:下面所有滑动的集合
- Swipeleft:向左滑动
- Swiperight:向右滑动
- Swipeup:向上滑动
- Swipedown:向下滑动
<div id="test" class="test">事件区域</div>
<div id="result" class="result">事件结果:向左滑动触发<br /></div>
//创建一个新的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);
});
