移动端事件

一、移动端事件类型

  • touchstart:手指按下事件,类似 mousedown
  • touchmove:手指移动事件,类似 mousemove
  • touchend 手指抬起事件,类似 mouseup
var box = document.querySelector('.container');
box.addEventListener('touchstart', () => {
  console.log('手指按下去了');
});
box.addEventListener('touchmove', () => {
  console.log('手指滑动了');
});
box.addEventListener('touchend', () => {
  console.log('手指抬起了');
});

二、事件对象

  • changedTouches:触发当前事件的手指列表,也就是涉及当前(引发)事件的触摸点的列表
  • targetTouches:位于当前 DOM 元素上的手指列表,也就是当前对象上所有触摸点的列表
  • touches:位于当前屏幕上的所有手指列表(必需至少有 1 个手指在添加触发事件的元素上),也就是当前屏幕上所有触摸点的列表
box.addEventListener('touchstart', (e) => {
  console.log(e.changedTouches);
  console.log(e.targetTouches);
  console.log(e.touches);
});

三、移动端事件和 PC 端事件区别

虽说有了移动端专属的事件,并不意味着原本 PC 端的浏览器事件就不能用了,但是还是推荐尽量使用移动端的专属事件,因为 PC 端的事件并不是专门为移动端设计的,因此会存在各种各样的问题,

1、触发点区别

PC

  • mousemove:不需要鼠标按下,但是必需在元素上才能触发

  • mouseup:必需在元素上抬起才能触发

移动端

  • touchmove:必需手指按下才能触发,但是,按下后不在元素上也能触发

  • touchend:不需要在元素上抬起就能触发

2、触发顺序

触发顺序依次为:touchstart → touchend → mousedown → click → mouseup

3、touchstartclick 的区别
  • touchstart 为手指碰到元素就触发
  • click 为手指碰到元素并且抬起才会触发

四、移动端事件的bug

300ms延迟问题

为什么移动端点击事件要加 300ms 延迟呢?

早在 2007 年初,苹果公司在发布首款 iPhone 前夕,遇到一个问题:当时的网站都是为大屏幕设备所设计的。于是苹果的工程师们做了一些约定,应对 iPhone 这种小屏幕浏览桌面端站点的问题。

这当中最出名的,当属双击缩放( double tap to zoom ),这也是会有上述 300 毫秒延迟的主要原因。

双击缩放,顾名思义,即用手指在屏幕上快速点击两次,iOS 自带的 Safari 浏览器会将网页缩放至原始比例。 那么这和 300 毫秒延迟有什么联系呢?

假定这么一个场景: 用户在 iOS Safari 里边点击了一个链接。由于用户可以进行双击缩放或者双击滚动的操作,当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击操作。因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕。

鉴于 iPhone 的成功,其他移动浏览器都复制了 iPhone Safari 浏览器的多数约定,包括双击缩放,几乎现在所有的移动端浏览器都有这个功能。

2014 年,从 Chrome32 开始 Google 已经解决这个 300ms 延迟问题,只要定义了 viewport 就不会有 300ms 延迟问题。

除此之外,我们来看一下移动端事件和 PC 端事件之间的其他区别。虽然上面介绍的 3 个移动端事件,都能找到其在 PC 端中相似的事件,但是仔细一比较,也是存在如下区别的:

事件穿透

所谓事件穿透,是移动端上面一个非常有名的 Bug,其出现场景为:有两层重叠的元素,上面的元素有 touch 事件(点击后要消失),下面是一个默认会触发 click 事件的元素(a、表单元素、带 click 事件的元素),此时点击上一层的元素,下一层也同样会被点击。

为什么会存在事件穿透呢?

这是因为在移动端浏览器,事件执行的顺序是 touchstarttouchmovetouchedclick。而 click 事件有 300ms 的延迟,当 touchstart 事件把上层元素隐藏之后,隔了 300ms,浏览器触发了 click 事件,但是此时上层元素不见了,所以该事件被派发到了下层元素身上。

那么既然存在这个问题,该如何解决呢?

有一个最简单的解决方式,那就是取消事件的默认行为,如下:

box.addEventListener('touchstart', ev => {
  box.style.display = 'none';
  ev.preventDefault(); // 取消事件的默认动作
});

当我们阻止了 touchstart 事件的默认行为后,事件穿透也就随即消失。

五、移动端事件三方库

1、Swiper.js 轮播图库

官网地址:https://www.swiper.com.cn/

这是一个非常方便的制作轮播图的的第三方库,支持各种姿势的轮播,很多大厂也是在自己的移动端网页中使用这个库

2、Hammer.js 移动端手势库

官网地址:http://hammerjs.github.io/

优势

  • Hammer.js 不需要依赖任何其他的 JS 框架或者库,并且整个框架非常小,v2.0.4 版本只有 3.96kb

  • 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 主要事件如下:

image-20220330235011654

1、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);
});
2、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);
});
3、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);
});
4、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);
});
5、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);
});
6、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);
});
  • 19
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
移动端双指事件通常是用于实现缩放或者旋转操作的,常见的事件有touchstart、touchmove、touchend等。以下是一些常用的双指事件: 1. touchstart事件 当有两个手指同时放在屏幕上时,会触发touchstart事件。此时可以通过e.touches来获取所有手指的信息,如下所示: ```javascript document.addEventListener('touchstart', function(e) { if (e.touches.length === 2) { // 获取第一个手指的坐标 var x1 = e.touches[0].clientX; var y1 = e.touches[0].clientY; // 获取第二个手指的坐标 var x2 = e.touches[1].clientX; var y2 = e.touches[1].clientY; // 其他操作 } }, false); ``` 2. touchmove事件 当两个手指在屏幕上移动时,会触发touchmove事件。此时可以通过e.touches来获取所有手指的信息,如下所示: ```javascript document.addEventListener('touchmove', function(e) { if (e.touches.length === 2) { // 获取第一个手指的坐标 var x1 = e.touches[0].clientX; var y1 = e.touches[0].clientY; // 获取第二个手指的坐标 var x2 = e.touches[1].clientX; var y2 = e.touches[1].clientY; // 其他操作 } }, false); ``` 3. touchend事件 当两个手指中的任意一个离开屏幕时,会触发touchend事件。此时可以通过e.touches来获取所有手指的信息,如下所示: ```javascript document.addEventListener('touchend', function(e) { if (e.touches.length === 1) { // 只有一个手指,可以进行单指操作 } }, false); ``` 通过以上三个事件,我们可以实现双指操作的各种需求,比如缩放、旋转等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

[chao]

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值