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.