移动端事件

news/2025/3/16 1:22:31/

一、移动端事件类型

  • 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);
});

http://www.ppmy.cn/news/1274786.html

相关文章

如何搭建企业管理系统Odoo并远程访问管理界面【内网穿透】

文章目录 前言1. 下载安装Odoo&#xff1a;2. 实现公网访问Odoo本地系统&#xff1a;3. 固定域名访问Odoo本地系统 前言 Odoo是全球流行的开源企业管理套件&#xff0c;是一个一站式全功能ERP及电商平台。 开源性质&#xff1a;Odoo是一个开源的ERP软件&#xff0c;这意味着企…

历史上封禅泰山的君王

封禅泰山的意思&#xff0c;就是皇帝想表达一件事&#xff1a;哥的皇权是上天赐给哥的&#xff0c;你们都得听哥使唤才行&#xff01;顺便呢&#xff0c;再把自己的年终总结向老天爷汇报一下。不过一般皇帝可不敢封禅泰山&#xff0c;必须要有作为或者觉得自己有作为才会去。 …

LeetCode338. Counting Bits

文章目录 一、题目二、题解 一、题目 Given an integer n, return an array ans of length n 1 such that for each i (0 < i < n), ans[i] is the number of 1’s in the binary representation of i. Example 1: Input: n 2 Output: [0,1,1] Explanation: 0 -->…

【matlab】MATLAB 中矩阵操作与应用

引言 矩阵是 MATLAB 中最重要和常用的数据结构之一。它在科学计算、数据处理和算法设计中发挥着关键作用。本文将深入探讨 MATLAB 中的矩阵,包括矩阵的定义、创建、索引、运算以及一些常见的应用。 1. 矩阵的定义和创建 在 MATLAB 中,矩阵是一个二维的数值数组。可以使用不…

安装android studio

记录一下安装android studio的过程&#xff1a; 1.首先安装android studio到某一文件夹后&#xff0c;在C盘用户目录下可以看到.android文件夹。C:\Users\22515\AppData\Local\Google目录下也会出现AndroidStudio2022.2文件夹。&#xff08;注意&#xff1a;用户名&#xff0c…

内衣洗衣机好用吗?专门洗内衣内裤的热门小型洗衣机

随着人们的生活水平的提升&#xff0c;越来越多小伙伴来开始追求更高的生活水平&#xff0c;一些智能化的小家电就被发明出来&#xff0c;而且内衣洗衣机是其中一个。现在通过内衣裤感染到细菌真的是越来越多&#xff0c;所以我们对内衣裤的清洗频次会高于普通衣服&#xff0c;…

记录今日将C语言的Windows程序更改为python语言Windows程序,实现子窗口控制,类似微信程序框架最简单的原型

基本思路 为什么要选择python制作Windows应用程序&#xff0c;主要就是源代码直接展示&#xff0c;发现问题随时修改&#xff0c;同时可以不断增加新的功能方便。 由于C语言的Windows程序中结构类型在python中不能使用&#xff0c; 因此我们按照ctypes模块指导意见继承structu…

【超图】SuperMap iClient3D for WebGL/WebGPU —— 单体gltf模型与Blender中的方向对应关系

作者&#xff1a;taco 在很多包含动画的场景中&#xff0c;像模拟小人的行走、模拟火车的轨迹运行&#xff0c;又或者是模拟风力发电等等等。我们通常会加一些动画模型到里面。而有的时候可能会出现&#xff0c;这火车怎么倒着走啊&#xff01;这人怎么头朝下啊。这种方向的问题…