Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Includes Touch Events clientX/Y scrolling or not?

I'm trying to get touch coordinates relative to the viewport of browser from touch events (such as touchstart). I tried to get them from clientX/Y properties, but both actually return values including scrolling.

This is against spec, as it says clientX/Y should return coordinates without scrolling.

  • I tried adding/removing meta viewport tag - without success.
  • I tested it in iOS 4.3 on iPhone and Fennec nightly - both return values with scrolling.

What I'm doing wrong?

Thanks

like image 980
kuvik Avatar asked May 04 '11 15:05

kuvik


2 Answers

You're not doing anything wrong. It's a bug in older versions of webkit that occur when the page is scrolled. I have seen this bug in iOS4 and a different bug in Android 4.0.

I've found a way to detect the bugs and calculate the correct values. Hope this can be useful for others:

function fixTouch (touch) {
    var winPageX = window.pageXOffset,
        winPageY = window.pageYOffset,
        x = touch.clientX,
        y = touch.clientY;

    if (touch.pageY === 0 && Math.floor(y) > Math.floor(touch.pageY) ||
        touch.pageX === 0 && Math.floor(x) > Math.floor(touch.pageX)) {
        // iOS4 clientX/clientY have the value that should have been
        // in pageX/pageY. While pageX/page/ have the value 0
        x = x - winPageX;
        y = y - winPageY;
    } else if (y < (touch.pageY - winPageY) || x < (touch.pageX - winPageX) ) {
        // Some Android browsers have totally bogus values for clientX/Y
        // when scrolling/zooming a page. Detectable since clientX/clientY
        // should never be smaller than pageX/pageY minus page scroll
        x = touch.pageX - winPageX;
        y = touch.pageY - winPageY;
    }

    return {
        clientX:    x,
        clientY:    y
    };
}

This function has to be called for each touch in the event.touches array.

like image 162
gregers Avatar answered Oct 21 '22 12:10

gregers


Try this

event.touches[0].pageX

Note that it is always event.touches even if you define your event like this (using jquery here)

$("body").bind('touchmove', function(e){ 
//stops normal scrolling with touch
e.preventDefault();

console.log(event.touches[0].pageX)

})

;

The Safari guide provides more detail

like image 21
Thomas Brasington Avatar answered Oct 21 '22 12:10

Thomas Brasington