js实现多点触控
多点触控基础概念
多点触控通过监听触摸事件(touchstart、touchmove、touchend、touchcancel)实现。每个触摸点会生成一个Touch对象,包含位置、标识符等信息,所有触摸点存储在TouchList中。
监听触摸事件
通过addEventListener绑定触摸事件,事件对象包含touches(所有当前触摸点)、changedTouches(本次事件变化的触摸点)等属性:
element.addEventListener('touchstart', handleTouchStart);
element.addEventListener('touchmove', handleTouchMove);
element.addEventListener('touchend', handleTouchEnd);
function handleTouchStart(e) {
const touches = e.touches; // 获取所有触摸点
console.log(`${touches.length}点触控开始`);
}
跟踪多个触摸点
通过Touch.identifier唯一标识每个触摸点,可用于跟踪移动轨迹:
let activeTouches = {};
function handleTouchMove(e) {
Array.from(e.changedTouches).forEach(touch => {
activeTouches[touch.identifier] = {
x: touch.clientX,
y: touch.clientY
};
});
// 处理两指缩放
if (Object.keys(activeTouches).length === 2) {
const keys = Object.keys(activeTouches);
const distance = Math.hypot(
activeTouches[keys[0]].x - activeTouches[keys[1]].x,
activeTouches[keys[0]].y - activeTouches[keys[1]].y
);
console.log(`当前两指距离: ${distance}px`);
}
}
处理触摸结束
清除已结束的触摸点记录:
function handleTouchEnd(e) {
Array.from(e.changedTouches).forEach(touch => {
delete activeTouches[touch.identifier];
});
}
手势识别示例(缩放/旋转)
通过计算两点间的距离和角度变化实现手势识别:
let initialDistance = 0;
let initialAngle = 0;
function handleTouchStart(e) {
if (e.touches.length === 2) {
const touch1 = e.touches[0];
const touch2 = e.touches[1];
initialDistance = Math.hypot(
touch1.clientX - touch2.clientX,
touch1.clientY - touch2.clientY
);
initialAngle = Math.atan2(
touch2.clientY - touch1.clientY,
touch2.clientX - touch1.clientX
);
}
}
function handleTouchMove(e) {
if (e.touches.length === 2) {
const touch1 = e.touches[0];
const touch2 = e.touches[1];
// 计算缩放比例
const currentDistance = Math.hypot(
touch1.clientX - touch2.clientX,
touch1.clientY - touch2.clientY
);
const scale = currentDistance / initialDistance;
// 计算旋转角度(弧度)
const currentAngle = Math.atan2(
touch2.clientY - touch1.clientY,
touch2.clientX - touch1.clientX
);
const rotation = currentAngle - initialAngle;
console.log(`缩放比例: ${scale.toFixed(2)}, 旋转角度: ${(rotation * 180/Math.PI).toFixed(1)}°`);
}
}
注意事项
- 移动端需添加视口元标签:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> - 使用
e.preventDefault()阻止默认行为(如页面滚动)时需谨慎 - 某些浏览器可能限制同时识别的触摸点数量(通常5-10个)
兼容性处理
可通过检测事件存在实现优雅降级:

if ('ontouchstart' in window) {
// 支持触摸事件
} else {
// 回退到鼠标事件
}
以上代码实现了基础的多点触控跟踪和常见手势识别,可根据具体需求扩展更多交互功能。
