Blog (my web musings)

Find out what's interesting me, get tips, advice, and code gems that don't fit elsewhere.


Search Blog


Let visitors 'feel' their way around the interactive areas of your website by adding support for native swipe gestures on touch devices. I'll be using my earlier RWD CSS3 Any Content Slider (JS auto-play) as a demo, but you can easily take away from this post to add touch gestures to your own apps... Need some other ideas?

Website features that may benefit from a left or right swipe

  • a content slider (progress back and forth between slides)
  • an image gallery (progress back and forth between images)
  • an interactive list (add or remove items)
  • tabbed content/pages (navigate to adjacent tabs or pages)
  • product images (swipe between the front and back view of a t-shirt)
  • novelty gaming visuals (turn an avatar around to check battle dress!)

Adding swipe gesture support

Now to add the swipe gesture support. There are lots of touch event libraries on the web today - many that rely on bulkier dependencies, such as jQuery or MooTools - but I wanted to go as lightweight as possible, so I started looking for a standalone touch library. I landed on a this list of touch event libraries and headed for the "Other" section. Touch and Hammer looked the most appealing of the bunch but as they offer additional support for pinch and tap-related gestures too, I wondered if I could get something even more lightweight - something that ONLY provided swipe support, because that's all I wanted.

Further research lead me to a contributor-submitted function at StackOverflow - this touch events handler function that only supports swipe left, right, up and down - it also includes support for 'fast click', which is useful for eliminating the 300ms delay, but I'm only interested in the swipe support for now.

Here's the refined and slightly modified version of the swipe gesture / touch events handler script;

(function(l){ 
var M=Math,ce,cx,cy,dx,dy,b,f,i,m,s,t=function(e,i){m=i;i=e.touches; return{x:i[0].pageX,y:i[0].pageY,z:i.length}};
for(i in s={touchcancel:function(e){m=0},touchstart:function(e){b=t(e,0)},touchmove:function(e){f=t(e,1)},touchend:function(e){if(b.z>1)return;ce=l.createEvent('CustomEvent');
ce.initCustomEvent(m?(M.max(dx=M.abs(cx=f.x-b.x),dy=M.abs(cy=f.y-b.y))>25?dx>dy?cx<0?'l':'r':cy<0?'u':'d':'fc'):'fc',true,true,b);e.target.dispatchEvent(ce);}
}) l.addEventListener(i,s[i],false)})(document);

To make use of this delightfully lightweight snippet, include it in your page (between the usual <script> tags) and then assign your swipe functions to different swipe directions in an event listener, like so;

element.addEventListener('r', rightFunction, false); // swipe right
element.addEventListener('l', leftFunction, false); // swipe left

Here's a very simple demo using a div... a very boring, grey div. (HTML markup for that div: <div class="div" id="div"></div>). Not very exciting, is it? And it will stay that way on desktop (without touch), but view the page on a touch device, and you'll have swipe power at your fingertips! Here's the JavaScript for the simple demo;

var myDiv = document.getElementById('div');

function up(){ myDiv.style.backgroundColor = 'green'; }
function down(){ myDiv.style.backgroundColor = 'yellow'; }
function left(){ myDiv.style.backgroundColor = 'red'; }
function right(){ myDiv.style.backgroundColor = 'blue'; }

myDiv.addEventListener('u', up, false); // swipe up
myDiv.addEventListener('d', down, false); // swipe down
myDiv.addEventListener('l', left, false); // swipe left
myDiv.addEventListener('r', right, false); // swipe right

For the benefit of those who can't test on touch, we have a different colour-change function attached to each directional swipe;

  • swipe up, the div turns green
  • swipe down, the div turns yellow
  • swipe left, the div turns red
  • swipe right, the div turns blue

So, let's take what we've learned from this simple demo and apply it to the RWD CSS3 Any Content Slider (JS auto-play).

Adding Swipe Support to the RWD CSS3 Any Content Slider

The first thing to change is the autoSlider() function. This is what creates the 'auto-play' feature by sequentially checking the slider's radio buttons, but it was previously only travelling in one direction; forwards, or left. To give it the option of also travelling backwards (right), we need to pass in a direction parameter and provide a switch to change direction, depending on which condition is met. Additions to the code are in red;

function autoSlider(slider, direction){
    var slides = document.getElementsByName(slider);
    for(var i = 1; i < slides.length; ++i){
       if(slides[i].checked == true){
           (navigator.appVersion.indexOf("MSIE 9") == -1) ? jump = 2 : jump = 3;
           if(direction == 'r'){ // right
               (i == 1) ? slides[slides.length - jump].checked = true : slides[i-1].checked = true; // backwards
               } else { // left

               (i == slides.length - jump) ? slides[1].checked = true : slides[i+1].checked = true; // forwards
               }
           break;
           }
        }
    }

Now we create 2 new swipe functions, that will each contain the autoSlider() function along with this new direction parameter - left or right;

function swipesliderLeft(){ // swipe left 
    autoSlider('slider', 'l'); // pass 'l' (left) direction to autoSlider() function
    stopSlider();
    }
function swipesliderRight(){ // swipe right
    autoSlider('slider', 'r'); // pass 'r' (right) direction to autoSlider() function
    stopSlider();
    }

I've included the stopSlider() function too so that the slider doesn't continue moving once the user interacts with it (how annoying would that be?!)

Finally, we attach the new swipe functions to event listeners for left and right swipes on the #slider div;

slider.addEventListener('l', swipesliderLeft, false); // swipe left
slider.addEventListener('r', swipesliderRight, false); // swipe right

The lines above translate as;

Listen for a 'l' (left) touch event on the #slider div, and trigger the swipesliderLeft() function.

and

Listen for a 'r' (right) touch event on the #slider div, and trigger the swipesliderRight() function.

There. That was pretty easy.

Here's a link to the final demo - Responsive CSS3 Any Content Slider (with JavaScript auto-play, large touch-toggle and swipe support):

Demo

View the source to study and grab all the CSS, HTML and JS, etc.