Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Determine touch position on tablets with JavaScript

I have an object with the name "element". If somebody touches the tablet, I would like to return the x and y coordinates of the touch position relative to the object, i. e. the upper left corner of the object has the coordinates x=0 and y=0.

I know how to implement this on desktops:

$(function() {
$(document).mousedown(function(e) {
  var offset = $("#element").offset();
  var relativeX = (e.pageX - offset.left);
  var relativeY = (e.pageY - offset.top);
  alert(relativeX+':'+relativeY);
  $(".position").val("afaf");
});
});

So the word "mousedown" should be replaced by "touchstart", I guess. However, it still doesn't work.

How do I change the above code such that it works on tablets with "touchstart" instead of "mousedown"?

like image 922
Tall83 Avatar asked Feb 02 '17 02:02

Tall83


2 Answers

Christopher Reid's answer almost worked for me, but I had to make a few ajustments because originalEvent property was not part of the event when I was testing in Google Chrome version 81.0.4044.138 and Mozila Firefox version 76.0.1.

Since I found some answers that use directly the event and other that uses event.originalEvent property, I added a check to use the first if the latter is undefined.

So instead of:

var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];

I used:

var evt = (typeof e.originalEvent === 'undefined') ? e : e.originalEvent;
var touch = evt.touches[0] || evt.changedTouches[0];

So the full answer then becomes:

if(e.type == 'touchstart' || e.type == 'touchmove' || e.type == 'touchend' || e.type == 'touchcancel'){
    var evt = (typeof e.originalEvent === 'undefined') ? e : e.originalEvent;
    var touch = evt.touches[0] || evt.changedTouches[0];
    x = touch.pageX;
    y = touch.pageY;
} else if (e.type == 'mousedown' || e.type == 'mouseup' || e.type == 'mousemove' || e.type == 'mouseover'|| e.type=='mouseout' || e.type=='mouseenter' || e.type=='mouseleave') {
    x = e.clientX;
    y = e.clientY;
}
like image 129
Daniel Lavedonio de Lima Avatar answered Nov 14 '22 10:11

Daniel Lavedonio de Lima


UPDATE: See Daniel Lavedonio de Lima's answer below

You have to explicitly pull a touches object out of the event, it doesn't contain the coordinates directly. Look at line two of the code below.

Here is the code I always use to get touch/pointer coordinates:

    if(e.type == 'touchstart' || e.type == 'touchmove' || e.type == 'touchend' || e.type == 'touchcancel'){
        var touch = e.originalEvent.touches[0] || e.originalEvent.changedTouches[0];
        x = touch.pageX;
        y = touch.pageY;
    } else if (e.type == 'mousedown' || e.type == 'mouseup' || e.type == 'mousemove' || e.type == 'mouseover'|| e.type=='mouseout' || e.type=='mouseenter' || e.type=='mouseleave') {
        x = e.clientX;
        y = e.clientY;
    }

Put this inside an event listener that listens for any or all of those events and add your offset calculation and this should work.

like image 26
Christopher Reid Avatar answered Nov 14 '22 10:11

Christopher Reid