Javascript ontouchstart/move/end - getting wierd results

7.2k views Asked by At

I'm building this image gallery with swipe functions for tablets/smartphones. I was getting pretty odd results on the iPad so I decided to track it all the way back to the beginning and just print out when the different events occured.

The following code was supposed to alert something like: "start.move.move.move.end" after I've completed a swipe with my finger (the number of 'move's is determined by how long the swipe action is).

        itemWrap[0].ontouchstart = function(e) {
            _self.msg.push("start");

        }

        itemWrap[0].ontouchmove = function(e) {
            _self.msg.push("move");
        }

        itemWrap[0].ontouchend = function(e) {
            _self.msg.push("end");

            // join messages and alert to browser
            msg = _self.msg.join(".") || "empty";
            alert(msg);
        }

However, I'm getting very strange alerts, and they differ quite significantly on Android/iOS devices. On Android the results look as excpected most of the time:

"start.move.move.move.move.end"

"start.end" (when just flicking the screen)

"start.move.start.end" (this happens every other touch action)

But on the iPad I'm getting some really strange results. On the first touch action I'm getting exactly what I'm expecting, but on the second touch the alert containing the results ("start.move.move.move.end") fires immediately upon touching the screen, and it always contains the previous results. When I touch the screen the third time it is back to regular operation again, and so it goes for every other touch action.

I've looked around for someone with a similar problem but the closest I seem to get are users having problems with multi-touch actions (which I'm not interested in). Any suggestions as to why this is happening?

1

There are 1 answers

1
Piotr Borowski On

You have to remember that a touch is a multi-touch and it's not like a mouse event which is always one. Each time you get touch event (touchstart, touchstart, touchend) you get also identifier

itemWrap[0].ontouchstart = function(e) {
    // e.touches.length - number of touches
    // e.touches[e.touches.length - 1].identifier - last touch is the last one on the list
    // e.touches[e.touches.length - 1].pageX and .pageY - place of the touch
    _self.msg.push("start");
}

So when you do touchmove and touchend you have to check that identifier to see which touch was moved or ended. You can do it by saving that data in touchstart:

var t = {pageX:event.touches[index].pageX, pageY:event.touches[index].pageY, identifier:event.touches[index].identifier};
touches.push(t);

And then find correct touch in touchend by using

event.changedTouches[0].identifier

here you don't need to go through that list because it's always just one but you have to compare that identifier with these you saved in the list.

Hope this will help.