fingers

With smart phones everywhere and tablets popping up at an increasing speed I just thought that I could share this quick tutorial on how to make touch screen devices interact with the web. In other words: capturing touch screen events on your web page.

In this post I’ll show you how to make an object draggable on your iPhone/iPad/Android device (might work on other touch devices with decent browsers, just haven’t tested any other). As usual when dealing with web and interaction we’re going to use javascript.

Now, traditionally when handling mouse-events we can listen to either mousemove, mousedown, mouseup or onclick. However, these won’t work in your shiny new touch device. Instead we need to bind our function to the events touchstart, touchmove, touchend or touchcancel

Once you have an event handler registered, there are three ways of getting the touch parameters (e is the argument of the handler function):

  • e.touches – all the touches on a page
  • e.targetTouches – get all touches for the target element
  • e.changedTouches – changed touches for this event

These event properties will be arrays, so f.ex. to get the first touch event you would write something like this:

This is nice, because it allows you to handle multi touch aswell. Just check event.touches.length to get the number of touch events. However, pursuing our goal, to get the X and Y coordinates of the touch event we use the attributes pageX and pageY:

Check this page to see all available attributes

I’ll be using jQuery for simple event listener registration. There is, however, one pitfall when using it:
normally when adding event listeners using the addEventListener method you would get the browser event passed as the first argument to your handler. With jQuery, you get a special jQuery event, so in order to find the touch parameters you’ll have to access the original browser event using e.originalEvent.

So, the code then:

The code above will try to move an object with id “rect”, so just add the appropriate HTML/CSS and you’re done

Improving

Instead of binding the event handlers to ‘document’ we can bind them directly to the element that is going to be draggable. This way we allow multiple objects to be draggable simultaneously. Now, the code will like like this instead:

Since ‘this’ will be bound to the touched DOM-element when the event fires, we can use that instead of hardcoding the element that is going to be moved like I did in the previous code. This way you only need to eg. assign a certain class, ‘draggable’, to the element that is going to be draggable. Neat!

Make it a plugin and take care of offset

As a final touch, we can go ahead and wrap the functionality into a jQuery plugin, making objects draggable by just invoking a function on the jQuery set that has been selected. Also, as Ronald Harris pointed out here in the comments, the previous approach only works for elements which has a parent that is positioned statically. So we need to calculate the elements offset at touchstart and compensate for it while dragging. Here’s the code:

Demo

See the final demo at: http://sewa.se/drag/
Please note that the page will be extremely boring when accessed using your PC. Use your iPhone, Android phone, iPad or similar

Read more

Safari Reference: handling events