JS--M端事件
移动端(Mobile 端,简称 M 端)开发中,由于设备特性(触摸屏、手势操作等),需要处理一些与桌面端不同的事件。这些事件主要针对触摸交互、手势识别等场景
一、触摸事件(Touch Events)
触摸事件是 M 端最基础的交互事件,用于响应手指在屏幕上的操作:
事件名 | 触发时机 | 常用场景 |
---|---|---|
touchstart | 手指触摸到元素时触发 | 开始拖拽、播放动画 |
touchmove | 手指在元素上滑动时持续触发 | 拖拽元素、滑动控制 |
touchend | 手指离开屏幕时触发 | 结束拖拽、提交操作 |
touchcancel | 触摸被中断时触发(如弹窗弹出、电话接入) | 清理临时状态 |
事件对象属性(TouchEvent
)
触摸事件对象包含与触摸相关的关键信息:
touches
:当前屏幕上所有触摸点的列表(Touch
对象数组)。targetTouches
:当前元素上所有触摸点的列表。changedTouches
:触发当前事件的触摸点列表(如touchend
中是离开的触摸点)。
每个 Touch
对象包含位置信息:
clientX
/clientY
:触摸点相对于视口的坐标。pageX
/pageY
:触摸点相对于文档的坐标(含滚动距离)。
示例:监听触摸滑动方向
const box = document.getElementById('box');
let startX, startY;// 记录触摸开始位置
box.addEventListener('touchstart', function(e) {startX = e.touches[0].clientX;startY = e.touches[0].clientY;
});// 监听滑动过程
box.addEventListener('touchmove', function(e) {// 阻止页面默认滚动(可选)e.preventDefault();const moveX = e.touches[0].clientX - startX;const moveY = e.touches[0].clientY - startY;// 简单判断滑动方向if (Math.abs(moveX) > Math.abs(moveY)) {console.log(moveX > 0 ? '向右滑' : '向左滑');} else {console.log(moveY > 0 ? '向下滑' : '向上滑');}
});
二、手势事件(Gesture Events)
手势事件用于识别复杂的触摸交互(如缩放、旋转),通常基于两个手指的操作:
事件名 | 触发时机 | 常用场景 |
---|---|---|
gesturestart | 两个手指开始触摸时触发 | 开始缩放/旋转 |
gesturechange | 两个手指移动时触发(实时变化) | 调整缩放比例/角度 |
gestureend | 两个手指离开时触发 | 结束缩放/旋转 |
事件对象属性
scale
:手势的缩放比例(初始为 1,大于 1 是放大,小于 1 是缩小)。rotation
:手势的旋转角度(单位为度,正值为顺时针,负值为逆时针)。
示例:实现图片缩放旋转
const img = document.getElementById('img');
let currentScale = 1;
let currentRotation = 0;// 监听手势开始
img.addEventListener('gesturestart', function(e) {e.preventDefault(); // 阻止默认行为
});// 监听手势变化
img.addEventListener('gesturechange', function(e) {e.preventDefault();// 更新缩放和旋转currentScale *= e.scale;currentRotation += e.rotation;// 应用变换img.style.transform = `scale(${currentScale}) rotate(${currentRotation}deg)`;
});
三、触摸与点击的区别
click
事件:在移动端也会触发,但存在 300ms 延迟(历史原因,用于判断是否双击缩放),且在touchend
后才触发。touch
事件:无延迟,更适合需要快速响应的场景(如游戏、滑动交互)。
解决 click
延迟问题:
- 使用
touchstart
替代click
(需注意防止误触)。 - 添加
<meta name="viewport" content="width=device-width">
可消除部分浏览器的 300ms 延迟。 - 使用库(如 FastClick)优化。
四、常见问题与优化
-
触摸穿透(Touch Through):
- 现象:点击上层元素后,下层元素的
click
事件被触发。 - 解决:在
touchend
中使用e.preventDefault()
,或避免多层叠加可点击元素。
- 现象:点击上层元素后,下层元素的
-
滑动冲突:
- 现象:内部元素滑动时,页面整体也会滚动(如轮播图滑动 vs 页面滚动)。
- 解决:在
touchmove
中根据滑动方向判断是否阻止默认行为(e.preventDefault()
)。
-
事件防抖:
touchmove
触发频率极高,需通过防抖限制处理频率:
let isProcessing = false; box.addEventListener('touchmove', function(e) {if (!isProcessing) {requestAnimationFrame(function() {// 处理滑动逻辑isProcessing = false;});isProcessing = true;} });
五、库与框架支持
对于复杂手势(如滑动删除、捏合缩放),推荐使用成熟库简化开发:
- Hammer.js:轻量级手势库,支持滑动、缩放、旋转等。
- AlloyFinger:腾讯团队开发的移动端手势库,体积小、API 简洁。
总结
M 端事件的核心是触摸交互,主要包括:
- 基础触摸事件(
touchstart
/touchmove
/touchend
):处理单指滑动、点击等。 - 手势事件(
gesturestart
/gesturechange
/gestureend
):处理双指缩放、旋转等。