当前位置:首页 > 行业动态 > 正文

hammer.js的用法

引入库,创建实例,绑定元素,监听手势事件(如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);
});
0