移動端(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
):處理雙指縮放、旋轉等。