On Tuesday I had the chance to pair with Eric Koslow on the client project that I worked on with Brian Pratt last week. Eric did his apprenticeship during mine so we’ve paired quite a bit together. He’s a quick thinker who seems to know something about every toolset out there so I invariably learn something new every time we work together.

He was continuing to work on the JavaScript for the iPad web app, which meant tracking down some unexpected behavior and getting the app to respond to touches and swipes the way that it should.

The secret to handling touch events in Safari on iOS is that the mobile browser provides unique DOM elements that you can interact with. The ones that we worked with most were the targetTouches and touchEvent object. Apple’s documentation explains it best:

The system continually sends touchEvent objects to an application as fingers touch and move across a surface. A touch event provides a snapshot of all touches during a multi-touch sequence, most importantly the touches that are new or have changed for a particular target. A multi-touch sequence begins when a finger first touches the surface. Other fingers may subsequently touch the surface, and all fingers may move across the surface. The sequence ends when the last of these fingers is lifted from the surface. An application receives touch event objects during each phase of any touch.

So, in a nutshell, what happens is that targetTouches ends up being an array of touchEvent objects. These events are things like touchstart, touchmove and touchend, and can be mapped to the mouse events mousedown, mousemove and mouseup. These touchEvents have various properties, such as the X and Y coordinates of each event.

Unfortunately all the code we worked on is in the client repo so I’m going to need to update this post with some better examples after I follow up with Eric, but here’s a quick and dirty example:

Let’s say that you wanted to track how far a touch moved along the X- or Y-axis. Normally a touch that moved further along the X-axis would just move the page around on the mobile browser (and snap back into place), but you want to intercept it and do something like a “page swipe” so that you can advance to the next slide in an HTML presentation or the next photo in a web gallery.

function pageSwipe(event) {
    event.preventDefault();
    var movementThreshold = 100;    
    var xDistanceMoved = event.targetTouches[0].pageX - startX;
    var yDistanceMoved = event.targetTouches[0].pageY - startY;
    if (xDistanceMoved > yDistanceMoved && xDistanceMoved > movementThreshold)
        advanceToNextPage;
};

All this function does is grab the first element out of the targetTouches and ask what its X and Y coordinates are (pageX and pageY). By subtracting the starting X and Y values we can then determine just how far it moved. If the X distance is greater than Y and also greater than the “accidental movement” threshold, then you trigger the page swipe. (Again, not the greatest example, so I’ll definitely update the post with more).

I feel like Eric and I just “touched” on the tip of the iceberg when it came to event handling in mobile browsers. As so much web consumption moves to mobile I’m looking forward to learning more about it.