#

Jump to Table of Contents

# Touch Events and Abstractions

The `event-touch` module extends the whitelist of DOM events to include the native touch and gesture events and adds relevant information to event facades.

The `event-move` module adds a set of abstract events that adapt to the client environment to handle either touch or mouse input.

The `event-flick` module adds a "flick" event on top of the gesture abstraction layer to capture a user flicking an element with mouse or finger.

The `event-gestures` module is a rollup of these three, but will potentially roll in more gesture based events in the future.

## Using Touch Events

YUI DOM event support also extends to touch events. To use touch events in your application, you will need to include the `event-touch` module in your use statement.

The set of common low-level touch events, which exist on most touch-enabled OSes are supported:

- `touchstart`
- `touchmove`
- `touchend`
- `touchcancel`

Additionally, the iOS specific touch events, `gesturestart`, `gesturechange` and `gestureend`, are also supported. YUI doesn't replicate support for these events on other touch OSes currently, due to their lack of DOM level multi-touch support. At the point at which they do expose multi-touch information in the lower level touch events, we can build in cross-platform support for multi-touch gestures.

    node.on("touchstart", function () {
        this.addClass("detached");
    });

#### The Touch Event Facade

The event facade passed to touch events has the common set of touch specific array properties available:

- `touches`
- `changedTouches`
- `touchTargets`

These event objects in these arrays are also normalized, just the same as the event object pass to any other DOM listener.

The event object for the iOS gesture events have `scale` and `rotation` properties, the same as the native event object.

## Cross-Device Gesture Support

The `event-move` module provides the following events that roughly relate to the associated touch or mouse event, depending on the client device:

Abstract event | Mouse event | Touch event
--- | --- | ---
`gesturemovestart` | `mousedown` | `touchstart`
`gesturemove` | `mousemove` | `touchmove`
`gesturemoveend` | `mouseup` | `touchend`

I say "roughly" because the gesture events aim to encapsulate common interactions rather than just serving as a relay to other events. Where this comes out is in the additional configuration that can be included in the subscription as a third argument.

    // Notify me when the user puts a finger down, or mouses down on
    // the car node
    car.on("gesturemovestart", alignForMove, {

        // fire the event only after 300ms of continuous contact...
        minTime: 300,

        // ...or if the finger/mouse moves more than 3px
        minDistance: 3
    });

    // Move the car node when the user moves the finger or mouse.
    // Note the `this` override parameter is shifted to account for
    // the configuration param
    car.on("gesturemove", car.move, null, car);

    // Notify me when the user lifts their finger, or lets go of
    // the mouse button (only if a gesturemovestart was received
    // on the node).
    car.on("gesturemoveend", screechingHalt);

The complete set of configuration parameters for the gesture events is in the API docs.

#### Related Events

The three gesture events are related to each other. They are notifications for the start, progress, and end of the same gesture. `gesturemove` and `gesturemoveend` subscriptions won't execute unless a `gesturemovestart` happens.

If you need them to fire separately, such as when attaching and detaching subscribers dynamically, the `gesturemove` and `gesturemoveend` events can be subscribed to individually by configuring `standAlone: true`

    // Doesn't require an associated `gesturemovestart` subscription
    Y.one("doc").on("gesturemove", function(e) {...}, {
        standAlone:true
    });

Under the hood, the DOM listeners which monitor mousemove/touchmove and mouseup/touchend are bound to the `document` by default. The node only provides the shared context to relate the three events.

## Flick Gesture Event

The flick gesture event is fired whenever the user initiates a flick gesture (with a finger or the mouse) on the node where the listener is attached.

    myNode.on("flick", function(e) {

      // Some of the flick specific data on the event facade

      var flick = e.flick,
          velocity = flick.velocity,
          distance = flick.distance,
          axis = flick.axis,
          startX = flick.start.pageX,
          startY = flick.start.pageY,

      // The event object itself is the event object for
      // the event which concludes the flick (the mouseup or touchend)

          endX = e.pageX,
          endY = e.pageY,
          endTarget = e.target;

    });

Like with the supporting gesture events, when subscribing to `flick`, you can also pass additional configuration to control when and how the flick subscriber is notified.

    // Custom config, with no context or extra args
    myNode.on("flick", flickHandler, {

        // only notify me if the flick covered
        // more than 20px and was faster than 0.8 px/ms
        minDistance: 20,
        minVelocity: 0.8,

        // prevent the default behavior for the
        // underlying mouse/touch events
        preventDefault: true
    });

    // Another option to avoid confusion when specifying the `this`
    // override or bound arguments for events with custom signatures
    // is to use Y.bind
    myNode.on("flick", Y.bind(o.flickHandler, o, arg1), {
        minDistance: 20,
        minVelocity: 0.8,
        preventDefault: true
    });

    // Alternately, make sure to account for the additional subscription
    // parameter by passing null if there is no configuration.
    myNode.on("flick", o.flickHandler, null, o, arg1);

The complete set of configuration parameters for the `flick` event is in the API docs.

## Caveats

1. The `flick` event doesn't (yet) support delegation.
2. The `delegate()` signature for the gesture events is `node.delegate('gesturemove', callback, filter, gestureConfig)`, reversing the order of the delegation filter and extra params from the `hover` and `key` events. This may be changed in a future release.