Hammer JS - Documentation

What is Hammer.js?

Hammer.js is a lightweight JavaScript library that allows you to easily add touch gestures to your web applications. It provides a consistent and cross-browser API for detecting various touch events such as taps, swipes, pinches, and rotates, abstracting away the complexities of handling different browser and device implementations. Instead of dealing with raw touch events, you can use Hammer.js’s high-level gestures, simplifying development and improving consistency across platforms.

Why use Hammer.js?

Using Hammer.js offers several key advantages:

Setting up Hammer.js: Installation and Inclusion

Hammer.js can be included in your project in a few ways:

<script src="https://hammerjs.github.io/dist/hammer.js"></script>
npm install hammerjs

Then, import it into your JavaScript code:

import Hammer from 'hammerjs';

After including Hammer.js, you can start using its API to detect and respond to gestures.

Browser Compatibility

Hammer.js supports a wide range of modern browsers and devices. While it aims for broad compatibility, optimal performance and support for all features are generally best achieved using modern, up-to-date browsers. Refer to the official Hammer.js documentation and release notes for the most up-to-date compatibility information, as browser support may evolve over time. Generally, you can expect good support across major desktop browsers and mobile browsers on iOS and Android.

Getting Started with Hammer.js

Creating a Hammer Instance

The first step to using Hammer.js is creating a Hammer instance. This instance is associated with a specific DOM element and will listen for gestures on that element. You create a Hammer instance using the Hammer constructor, passing the target element as an argument. Optionally, you can also pass a configuration object to customize the behavior.

// Get the target element
const element = document.getElementById('myElement');

// Create a Hammer instance
const hammer = new Hammer(element);

// Optionally, pass a configuration object (see below for details)
//const hammer = new Hammer(element, {
//  recognizers: [/* ... */]
//});

This creates a hammer object that you can use to manage gesture recognition for the element with the ID myElement.

Recognizers: Understanding the Basics

Hammer.js uses recognizers to detect different gestures. A recognizer is a specific type of gesture, such as a tap, swipe, pinch, or rotate. Each recognizer has its own set of criteria for determining if a gesture has occurred. By default, Hammer.js includes several built-in recognizers, and you can also create custom recognizers for more specialized needs. Some common built-in recognizers include:

Each recognizer can have options to fine-tune its behavior (e.g., specifying minimum swipe distance or velocity).

Event Handling

Hammer.js uses events to notify you when a gesture has occurred. You add event listeners to the Hammer instance using the on() method. The first argument is the gesture event name (e.g., 'tap', 'swipe', 'pinch'), and the second is a callback function that will be executed when the event occurs. The callback function receives a event object containing information about the gesture.

hammer.on('tap', (ev) => {
  console.log('Tap event:', ev);
});

This code adds a listener for the tap event. When a tap occurs on myElement, the callback function will be executed, and the ev object will contain details like coordinates, timestamp and more. Other events like swipeleft, swiperight, pinchin, pinchout, rotate etc, are also available.

Basic Example: Detecting Taps

This example shows how to detect taps on an element:

<!DOCTYPE html>
<html>
<head>
  <title>Hammer.js Tap Example</title>
  <script src="https://hammerjs.github.io/dist/hammer.js"></script>
</head>
<body>
  <div id="myElement">Tap me!</div>
  <script>
    const element = document.getElementById('myElement');
    const hammer = new Hammer(element);
    hammer.on('tap', (ev) => {
      alert('Tapped!');
    });
  </script>
</body>
</html>

This code creates a div element, and when you tap it an alert box will appear.

Handling Multiple Recognizers

You can add multiple recognizers to a single Hammer instance. Hammer.js will automatically manage conflicts between recognizers to determine which gesture has occurred. You can achieve this by adding multiple on() handlers for different events or by providing an array of recognizers in the configuration object during instance creation.

hammer.on('tap', (ev) => {
  console.log('Tapped!');
});
hammer.on('swipe', (ev) => {
  console.log('Swiped:', ev.direction);
});

This code listens for both tap and swipe events on the same element. Hammer.js will handle the situation where a swipe might also trigger a tap, and typically choose the more significant gesture. More fine grained control can be gained through recognizer configuration.

Core Recognizers

Tap

The tap recognizer detects a quick touch and release on the element. It’s essentially a single touch event without significant movement.

Double Tap

The doubletap recognizer detects two consecutive taps within a short time and distance.

Press

The press recognizer detects a touch that is held down for a specified duration.

Swipe

The swipe recognizer detects a quick, sliding movement of the finger across the screen.

Pan

The pan recognizer detects dragging or panning movements. It’s triggered continuously while the finger is moving.

Pinch

The pinch recognizer detects a pinching or spreading gesture using two fingers.

Rotate

The rotate recognizer detects a rotation gesture using two fingers.

Release

The release recognizer is triggered when a single touch is released, it is not a gesture recognizer in the same sense as the others.

Advanced Recognizer Configuration

Event Properties

Hammer.js events provide a rich set of properties within the event object passed to your event handlers. These properties provide detailed information about the gesture, including:

Many of these properties are specific to certain recognizers; consult the individual recognizer documentation for details on which properties are available.

Recognizer Options (enable, direction, threshold, etc.)

Each recognizer has a set of options that you can use to customize its behavior. These options are passed as a JavaScript object when you create a recognizer (or when adding them to the Hammer instance’s recognizers array). Common options include:

For example, to customize the swipe recognizer to only detect horizontal swipes with a minimum velocity of 0.5:

const hammer = new Hammer(element, {
  recognizers: [
    [Hammer.Swipe, { direction: Hammer.DIRECTION_HORIZONTAL, velocity: 0.5 }]
  ]
});

Customizing Recognizer Behavior

Beyond the built-in options, you can further customize the behavior of recognizers by extending them or creating your own custom recognizers. This involves creating a class that inherits from Hammer.Recognizer and overriding its methods to implement your custom logic. This is advanced usage and requires a deeper understanding of the Hammer.js architecture.

Preventing Default Browser Behavior

Browser often have default behaviors for touch events (e.g., scrolling). To prevent these defaults from interfering with your gesture handling, use the preventDefault() method on the event object within your gesture handler.

hammer.on('pan', (ev) => {
  ev.preventDefault(); // Prevent default browser scrolling behavior
  // ... your pan handling logic ...
});

Use this carefully, as preventing default behavior can have unintended side effects. It might prevent scrolling or other essential browser actions.

Input Type Management

Hammer.js can handle different types of input (touch, mouse, pointer). By default, it attempts to use the most appropriate input type for the current device and browser. You can manage the input types using options during the Hammer instance creation or configuration.

Using Multiple Recognizers Simultaneously

Hammer.js allows you to use multiple recognizers on the same element. It intelligently manages conflicts between recognizers based on priority and criteria to select the most appropriate gesture. Order in the recognizers array can affect this selection.

Recognizer Priority and Conflicts

When multiple recognizers might match the same input sequence, Hammer.js uses a priority system to determine which recognizer should be triggered. Recognizers with higher priority are checked first. You can influence priority by the order you define the recognizers in the configuration. If you create a custom recognizer, you will need to define its priority explicitly. Understanding this priority order is crucial for resolving potential conflicts when using several recognizers on the same element.

Advanced Techniques

Using Hammer.js with Frameworks (React, Angular, Vue)

Hammer.js can be integrated into various JavaScript frameworks. The specific implementation details vary depending on the framework, but the general approach is consistent:

In all cases, the core Hammer.js API remains the same; the framework integration mostly manages the lifecycle and DOM element access.

Integration with Other Libraries

Hammer.js can often be combined with other JavaScript libraries. However, ensure that there are no conflicts between event handling or DOM manipulation. For example, if you use a library that already handles touch events, you might need to carefully coordinate the event handling to avoid conflicts or unexpected behavior. Pay close attention to event priorities and how each library interacts with the underlying DOM events.

Creating Custom Recognizers

For gestures not covered by the built-in recognizers, you can create your own. This involves subclassing Hammer.Recognizer and overriding methods like recognizeWith, canRecognizeWith, getTouchAction, and the core recognition methods (onTouchStart, onTouchMove, onTouchEnd). You’ll define the logic to detect your custom gesture and emit custom events. This is advanced usage and requires a solid understanding of gesture recognition and Hammer.js’s internal workings.

Performance Optimization

For optimal performance:

Troubleshooting Common Issues

Common issues and their solutions:

Accessibility Considerations

Ensure your application remains usable for users with disabilities:

API Reference

This section provides a concise overview of the Hammer.js API. For complete and up-to-date details, refer to the official Hammer.js documentation.

Hammer Instance Methods

The Hammer instance (created using new Hammer(element, [options])) provides several methods for managing gesture recognition:

Recognizer Object Properties and Methods

Each recognizer object (accessible through hammer.get('recognizerName')) has properties and methods to control its behavior. Key properties include:

Methods available on a recognizer instance are limited but important, enabling dynamic changes to its behavior:

Event Object Properties

The event object passed to the event handlers contains comprehensive information about the gesture:

Remember to check the documentation for the specific properties available for each type of event. The properties listed are common, but not exhaustive.

Examples and Use Cases

This section showcases common use cases for Hammer.js and provides conceptual guidance. Specific implementation details will depend on your application’s structure and design.

A common use case involves creating an image gallery with touch gestures for navigation. You can use swipe gestures to move between images, pinch to zoom, and potentially double-tap to zoom in/out.

Touch-Enabled Navigation Menu

A touch-enabled navigation menu can use swipe gestures to reveal or hide the menu, or tap gestures to select menu items.

Scalable and Rotatable Maps

Maps often benefit from pinch-to-zoom and rotate gestures.

Drag-and-Drop Interface

Hammer.js can facilitate drag-and-drop functionality. Use the pan recognizer to track the element’s movement, updating its position based on the deltaX and deltaY properties.

Gesture-Based Game Controls

Many games benefit from intuitive gesture controls. You can use various recognizers for different actions: swipes for movement, taps for actions, pinches for zooming, and more.

Remember that these are high-level overviews. The specific implementation details depend on your project’s requirements, UI framework, and any other libraries you are using. Careful consideration of event handling, animation, and error handling are crucial to create a robust and user-friendly experience.