上一篇
hammer.js的用法
- 行业动态
- 2025-05-10
- 8
引入库,创建实例,绑定元素,监听手势事件(如tap、pan),在回调中处理逻辑
Hammer.js 是一款轻量级 JavaScript 库,专为处理移动端手势操作而设计,支持点击、拖拽、缩放、旋转等多种交互行为,它通过封装原生触摸事件(touch events),提供统一的跨平台手势识别接口,适用于移动端网页、混合开发应用(Hybrid App)以及 Electron 等桌面端项目,以下是 Hammer.js 的核心用法及实践指南。
安装与引入
安装方式
- CDN 引入:适合快速测试或小型项目
<script src="https://hammerjs.github.io/dist/hammer.min.js"></script>
- npm 安装:适合模块化项目管理
npm install hammerjs --save
- 直接下载:从官网(https://hammerjs.github.io/)下载压缩包,解压后引入
hammer.js
文件。
模块化导入(ES6)
import Hammer from 'hammerjs'; const myElement = document.getElementById('target'); const hammer = new Hammer(myElement);
基础用法与核心概念
初始化实例
Hammer.js 的核心是创建 Hammer
实例并绑定到 DOM 元素:
const element = document.querySelector('.gesture-target'); const hammer = new Hammer(element);
监听手势事件
通过 on
方法绑定事件回调,支持多种手势类型:
hammer.on('tap', function(e) { console.log('Tap detected!', e); }); hammer.on('pan', function(e) { console.log('Pan direction:', e.direction); });
事件类型 | 触发条件 | 常用属性 |
---|---|---|
tap | 快速点击屏幕 | e.center (点击坐标) |
pan | 单指拖动 | e.deltaX , e.deltaY (位移距离) |
pinch | 双指缩放 | e.scale (缩放比例) |
rotate | 双指旋转 | e.angle (旋转角度) |
press | 长按屏幕 | e.duration (按压时长) |
swipe | 快速滑动(需设置阈值) | e.direction (滑动方向) |
事件对象详解
每个手势事件会返回包含详细信息的对象 e
,
hammer.on('pan', function(e) { // 阻止默认行为(如滚动) e.preventDefault(); // 获取手势中心点坐标 const centerX = e.center.x; const centerY = e.center.y; // 判断拖动方向 if (e.direction === Hammer.DIRECTION_LEFT) { console.log('向左拖动'); } });
高级特性与配置
自定义手势识别
通过 recognizer
配置自定义手势行为:
const hammer = new Hammer(element, { recognizers: [ [Hammer.Pan, { threshold: 10 }], // 最小移动距离 10px [Hammer.Pinch, { enable: true }], // 启用缩放手势 [Hammer.Rotate, { enable: false }], // 禁用旋转手势 ], });
多手势优先级管理
当多个手势同时触发时,可通过 set
方法调整优先级:
hammer.get('pan').set({ priority: 1 }); // 优先级高的手势优先触发 hammer.get('pinch').set({ priority: 0 });
事件防抖与节流
结合 Lodash 等工具库优化高频触发的手势事件:
import { throttle } from 'lodash'; hammer.on('pan', throttle(function(e) { console.log('Pan event triggered'); }, 100)); // 每 100ms 触发一次
实战场景与代码示例
场景 1:实现图片缩放与拖动
<div id="image-container" style="width:300px;height:300px;overflow:hidden;"> <img id="target-image" src="example.jpg" style="width:100%;"> </div> <script> const imageElement = document.getElementById('target-image'); const hammer = new Hammer(imageElement); let scale = 1; let lastScale = 1; // 缩放手势 hammer.on('pinch', function(e) { scale = Math.max(1, Math.min(lastScale e.scale, 3)); // 限制缩放范围 imageElement.style.transform = `scale(${scale})`; lastScale = scale; }); // 拖动手势(需配合缩放) hammer.on('pan', function(e) { if (scale === 1) return; // 仅在缩放后允许拖动 const container = document.getElementById('image-container'); const x = e.deltaX + parseInt(container.style.left || '0'); const y = e.deltaY + parseInt(container.style.top || '0'); container.style.left = `${x}px`; container.style.top = `${y}px`; }); </script>
场景 2:滑动删除列表项
const listItem = document.querySelector('.list-item'); const hammer = new Hammer(listItem); let startX = 0; hammer.on('panstart', function(e) { startX = e.center.x; }); hammer.on('panmove', function(e) { const deltaX = e.deltaX; const translate = deltaX (startX e.center.x); listItem.style.transform = `translate3d(${translate}px, 0, 0)`; }); hammer.on('panend', function(e) { if (Math.abs(e.deltaX) > 50) { // 滑动超过 50px 触发删除 listItem.remove(); } else { listItem.style.transform = 'translate3d(0, 0, 0)'; // 回弹 } });
常见问题与解决方案
手势冲突问题
现象:缩放时误触发拖动,或点击延迟。
解决方案:调整手势优先级,禁用默认行为:
hammer.get('pan').set({ lock: true }); // 缩放时锁定拖动 hammer.on('tap', function(e) { e.preventDefault(); }); // 阻止浏览器默认点击行为
性能优化建议
- 减少事件绑定:仅在需要的元素上初始化 Hammer.js。
- 销毁实例:页面卸载时调用
hammer.stop()
释放资源。 - 合并事件处理:使用
hammer.recognizers
统一管理手势逻辑。
FAQs(常见问题解答)
Q1:Hammer.js 是否支持老旧浏览器?
A:Hammer.js 依赖现代浏览器的 TouchEvent
API,IE10+ 及以上版本支持,若需兼容 IE9,需引入 Polyfill(如 touch-events-polyfill
)。
Q2:如何同时处理多个元素的手势?
A:为每个目标元素单独创建 Hammer
实例,或使用事件委托。
document.querySelectorAll('.gesture-target').forEach(el => { new Hammer(el).on('tap', handleTap); });