Flickable.js: A Zepto Plugin to Enable Touch Gestures on Any HTML Element
by Tom on Tuesday, February 14th, 2012

Lately I’ve been working on a mobile web application using HTML + PhoneGap to create an iOS app. For Javascript I’ve been using Zepto to handle basic gesture events, but for more complex touch interactions I found Zepto lacking.
So I created my first Zepto plugin called Flickable (jump to download). The plugin allows you to make any element touchable; useful for flicking between sections, or sliding elements around the page.
Demos
Before I get to how Flickable works, here are some demos to show you what it does. These demos are currently optimised for iOS and Android devices only. iOS 5+ is recommended because of its GPU acceleration for CSS transitions.
Page Flipper
This demo allows the user to drag or flip between pages, similar to the way you would flip through photos on a phone.
Thumbnail Slider
This is similar to the way the App Store allows you to flip through app screenshots, but it can also be used to allow users to slide through navigation items that don’t fit within a single page.
Vertical Jigsaw
Slide up or down on the three segments to match up the images.
How it works
Flickable is designed to be flexible and work around your markup. It doesn’t generate any wrapper elements and doesn’t need a special CSS file to be included.
Say you had this HTML setup:

My intension is to show just one of those green boxes (<section>) on the screen at a time, and allow the user to swipe between them. In this case I have placed the #flickable_wrapper element that contains the boxes inside a #wrapper element which has an overflow: hidden applied to it so that there is only room for 1 box at a time.
Now I can apply Flickable to it like so:
$('#flickable_wrapper').flickable({segments:3});
Flickable will automatically calculate the width of each segment by dividing the #flickable_wrapper width by the number of segments specified (in this case 3). That’s it! Now I can move #flickable_wrapper around with my finger and Flickable will snap to the nearest segment once I release.

See the Page Flipper demo above for an example of how this would work.
Installation
To install Flickable, first download the plugin file and include it in your HTML after Zepto.
<script type="text/javascript" src="libs/zepto.min.js"></script><script type="text/javascript" src="plugins/zepto.flickable.js"></script>
Usage
To use it, simply target the element you want to be Flickable, and apply the plugin to it. At minimum you should provide the number of segments Flickable will slice the element.
HTML:
<div id="wrapper"> <ul id="flickable-element"> <li>Content</li> <li>Content</li> <li>Content</li> </ul> </div>
JavaScript:
$('#flickable-element').flickable({segments:3});
Fallback for desktops
If you need to allow for non-touchscreens you can bind the available Flickable methods to click events, like so:
$('.next').click(function() {
$('#flickable-element').flickable('scrollNext');
});
Documentation
Event Callbacks
| Event | Type | Description |
|---|---|---|
| onCreate | function(flickableObjects) | Triggered when Flickable object is created. |
| onStart | function(eventData) | Triggered when a touch event begins. |
| onMove | function(eventData) | Triggered when the element is moved via a gesture in any direction. |
| onScroll | function(eventData) | Triggered when element snaps to the nearest segment in any direction. |
| onScrollPrev | function(eventData) | Triggered when element snaps to the previous segment. |
| onScrollNext | function(eventData) | Triggered when element snaps to the next segment. |
| onFlick | function(eventData) | Triggered when element user flicks in a valid direction. |
| onFlickLeft | function(eventData) | Triggered when element user flicks from right to left. |
| onFlickRight | function(eventData) | Triggered when element user flicks from left to right. |
| onFlickUp | function(eventData) | Triggered when element user flicks from bottom to top. |
| onFlickDown | function(eventData) | Triggered when element user flicks from up to down. |
| onEnd | function(eventData) | Triggered when the user lifts their finger off the screen, ending the touch event. |
Most events also include the event data object, which is structured like so:
eventData = {
// Starting touchpoint [x pos, y pos, timestamp]
start: {x:0, y:0, time: 0},
delta: {
// Previous touchpoint
prevPos: {x:0, y:0},
// Distance relative to original touchpoint
dist: {x:0, y:0},
// Direction of touch
// [-1 left/up, +1 right/down, 0 no movement]
dir: {x:0, y:0}
},
end: {
// Duration of touch
duration: 0,
// Speed of movement along x and y axis
speed: {x:0, y:0},
// +1/-1 if the touch was deemed to
// be a flick left/right up/down
flick: {x:0, y:0}
}
}
Options
| Option | Type | Default | Description |
|---|---|---|---|
| segments | Number | 5 | Number of segments in which to divide the target element. |
| flickThreshold | Float | 0.7 | Threshold in which a simple “touch and move” gesture becomes a “flick”.If you’re targeting Android, you may need to lower this to make it more sensitive because of Android’s lower frame rates for translate3d animations. |
| flickDirection | ‘x’ or ‘y’ | ‘auto’ | Direction in which to divide the element into sections, and in which the user can flick.If not specified, the direction will be automatically calculated based on which side of the target element is the longest. |
| preventDefault | Boolean | true | Whether or not to cancel default actions on the target element. Note that if this is set to false, the page will scroll with the gesture. |
Methods
| Method | Description | Example |
|---|---|---|
| segment | Gets or sets the current segment. Note segments start at 0. | $(‘#thing’).flickable(‘segment’); //gets current segment $(‘#thing’).flickable(‘segment’, 5); //sets segment to 5 |
| scrollNext | Scroll to next segment. | $(‘#thing’).flickable(‘scrollNext’); |
| scrollPrev | Scroll to previous segment. | $(‘#thing’).flickable(‘scrollPrev’); |
Download Flickable
Download and read full documentation on GitHub.
UPDATE: Added GitHub link.


