5
<title>Example: Supporting A Swipe Left Gesture</title>
6
<link rel="stylesheet" href="http://fonts.googleapis.com/css?family=Maven+Pro:400,700">
7
<link rel="stylesheet" href="../../build/cssgrids/grids-min.css">
8
<link rel="stylesheet" href="../assets/css/main.css">
9
<link rel="stylesheet" href="../assets/vendor/prettify/prettify-min.css">
10
<script src="../../build/yui/yui-min.js"></script>
15
<h1>Example: Supporting A Swipe Left Gesture</h1>
20
<div class="yui3-u-3-4">
22
<div class="content"><div class="intro">
24
This example shows how you can support a "swipeleft" gesture, built on
25
top of the synthetic "gesturemove" events, which work not only on touch
26
devices, but also on mouse based input devices.
30
<div class="example newwindow">
31
<a href="swipe-example-content.html" target="_blank" class="button">
32
View Example in New Window
38
<p>For the example, the two core modules we'll use are:</p>
41
<dt>The <code>event-move</code> module</dt>
43
Provides the <code>gesturemovestart</code>, <code>gesturemove</code> and <code>gesturemoveend</code>
44
low-level gesture events. These events are fired whenever the user
45
performs a move gesture (mouse button/finger down, mouse/finger move,
46
mouse button/finger up) with the mouse or their finger.
48
<dt>The <code>transitions</code> module</dt>
50
Provides transitions support, leveraging CSS transitions under the hood
55
<p>The YUI use statement for the example is shown below:</p>
57
<pre class="code prettyprint">YUI().use("node-base", "node-event-delegate", "transition", "event-move", function(Y) {
62
<h2>Delegating Gesture Move Events</h2>
65
The basic idea for the example is to listen for a <code>gesturemovestart</code> on a
66
list item, and when we get one, store its position, and then listen for a
67
gesturemoveend. If the gesturemoveend occurs more than X pixels to the left
68
of the start, then we've identified a "swipeleft" gesture. Future versions
69
of the library will package such logic into a higher level gesture event
74
For this example, since we're dealing with a list of items, rather than
75
attach individual listeners to each <li> in the list, we use
76
<code>delegate</code> on the parent <ul> element, which leads to better
77
performance and avoids having to add/remove listeners each time the
78
contents of the list change. The <code>gesturemovestart</code>, <code>gesturemove</code> and
79
<code>gesturemoveend</code> are synthetic events, and can all be used with <code>delegate</code>,
80
just like any DOM event.
84
We set up a delegate listener on the <ul> which listens for the
85
<code>gesturemovestart</code> event (<code>gesturemovestart</code> abstracts
86
<code>mousedown</code>/<code>touchstart</code> events under the hood). The delegate listener is
87
set up to be notified when the target of the <code>gesturemovestart</code> is an
88
<code><li></code>
91
<pre class="code prettyprint">Y.Node.one("#swipe").delegate("gesturemovestart", function(e) {
95
}, "li", { // filter for "li"
101
The <code>gesturemovestart</code> event supports a configuration object passed as an
102
additional subscription argument, which can be used to set minimum distance
103
and minimum time thresholds at which to fire the start event. The
104
configuration also supports the ability to prevent the default behavior
105
before the minimum time or distance thresholds kick in, which is what we do
106
above by passing <code>preventDefault:true</code>.
110
The advantage of the gesture synthetic events is that the developer can use
111
the same API without having to worry about whether or not the browser
112
platform is touch based or mouse based.
115
<h2>Gesture Move End</h2>
118
As mentioned above, the <code>gesturemovestart</code> listener is notified whenever a
119
<code>mousedown</code> or <code>touchstart</code> is received on a list item. The listener has
124
<dt><code>e.currentTarget</code></dt>
125
<dd>The list item targeted.</dd>
126
<dt><code>e.target</code></dt>
128
The element clicked on (it may be an element inside the targeted
129
list item, the span for example).
131
<dt><code>e.container</code></dt>
133
The element to which the delegate listener is attached (the ul in
139
The event facade also has the page coordinates for the <code>mousedown</code> or
140
<code>touchstart</code> event. We use the list item's <code>setData</code> method, to store the
141
<code>pageX</code> position for the start event, so we can compare it when we get the
142
<code>gesturemoveend</code> event. This way it's stored on the node instance, and we
143
don't need to pass it along separately to the <code>gesturemoveend</code> event, or
148
<code>getData</code>, <code>setData</code> and <code>clearData</code> are useful methods to store ad-hoc
152
<pre class="code prettyprint">Y.Node.one("#swipe").delegate("gesturemovestart", function(e) {
154
var item = e.currentTarget,
156
container = e.container,
160
item.setData("swipeStart", e.pageX);
162
item.once("gesturemoveend", function(e) {
164
var swipeStart = item.getData("swipeStart"),
166
isSwipeLeft = (swipeStart - swipeEnd) > MIN_SWIPE;
169
item.one(".myapp-delete").removeClass("myapp-hidden");
180
When we get the <code>gesturemovestart</code> event, we set up a listener for the
181
<code>gesturemoveend</code> event, so we can determine the end of the gesture, and
182
figure out if the user swiped left. Since we don't want to set up a new
183
listener every time we get a <code>gesturemovestart</code> we use <code>once</code> to set up the
184
<code>gesturemoveend</code> listener. <code>once</code> will detach the listener after it's been
185
invoked. Again, since <code>gesturemoveend</code> is a synthetic event, it works with
186
<code>once</code> just like any other DOM event.
190
In the <code>gesturemoveend</code> listener we check the page position of the event,
191
and if it's far enough to the left of the start position, we display the
192
"Delete" button by removing the hidden class which it contains.
198
To hide and remove the item when the delete button is pressed, we use the
199
<code>transition</code> method, to animate its opacity and height down to 0. Under the
200
hood transition will use CSS transition support where available (WebKit)
201
and set up timer based animation where not (IE). As with the gesture event
202
support, the developer gets to use the same API without having to worry
203
about the browser environment.
206
<pre class="code prettyprint">item = target.get("parentNode");
218
The second argument to transition above is a callback function, which is
219
invoked when the transition is complete. We use this support to remove the
223
<h2>Full Code Listing</h2>
225
<pre class="code prettyprint">YUI().use('node-base','node-event-delegate', 'transition', 'event-move', function (Y) {
229
Y.all(".myexample-hidden").removeClass("myexample-hidden");
231
Y.one("#swipe").delegate("gesturemovestart", function(e) {
233
var item = e.currentTarget,
235
container = e.container,
236
isDeleteButton = target.hasClass("myapp-delete");
238
// Prevent Text Selection in IE
239
item.once("selectstart", function(e) {
243
if (!isDeleteButton) {
245
container.all(".myapp-delete").addClass("myapp-hidden");
247
item.setData("swipeStart", e.pageX);
249
item.once("gesturemoveend", function(e) {
251
var swipeStart = item.getData("swipeStart"),
253
isSwipeLeft = (swipeStart - swipeEnd) > MIN_SWIPE;
256
item.one(".myapp-delete").removeClass("myapp-hidden");
261
item = target.get("parentNode");
263
if (item.get("id") != "kitkat" || confirm("Seriously? The KitKats?")) {
283
<div class="yui3-u-1-4">
284
<div class="sidebar">
288
<div class="sidebox">
290
<h2 class="no-toc">Examples</h2>
294
<ul class="examples">
297
<li data-description="Use the Event Utility to attach simple DOM event handlers.">
298
<a href="basic-example.html">Simple DOM Events</a>
303
<li data-description="Using the synthetic event API to create a DOM event that fires in response to arrow keys being pressed.">
304
<a href="synth-example.html">Creating an Arrow Event for DOM Subscription</a>
309
<li data-description="Supporting cross-device swipe gestures, using the event-move gesture events">
310
<a href="swipe-example.html">Supporting A Swipe Left Gesture</a>
330
<div class="sidebox">
332
<h2 class="no-toc">Examples That Use This Component</h2>
336
<ul class="examples">
345
<li data-description="Shows how to extend the base widget class, to create your own Widgets.">
346
<a href="../widget/widget-extend.html">Extending the Base Widget Class</a>
351
<li data-description="Creating an accessible menu button using the Focus Manager Node Plugin, Event's delegation support and mouseenter event, along with the Overlay widget and Node's support for the WAI-ARIA Roles and States.">
352
<a href="../node-focusmanager/node-focusmanager-3.html">Accessible Menu Button</a>
357
<li data-description="Use IO to request data over HTTP.">
358
<a href="../io/get.html">HTTP GET to request data</a>
363
<li data-description="Example Photo Browser application.">
364
<a href="../dd/photo-browser.html">Photo Browser</a>
369
<li data-description="Portal style example using Drag & Drop Event Bubbling and Animation.">
370
<a href="../dd/portal-drag.html">Portal Style Example</a>
383
<script src="../assets/vendor/prettify/prettify-min.js"></script>
384
<script>prettyPrint();</script>