Определите позицию касания на планшетах с помощью JavaScript

У меня есть объект с именем "элемент". Если кто-то касается планшета, я бы хотел вернуть координаты x и y позиции касания относительно объекта, то есть верхний левый угол объекта имеет координаты x=0 и y=0.

Я знаю, как реализовать это на настольных компьютерах:

$(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");
});
});

Так что слово "mousedown" следует заменить на "touchstart", я думаю. Тем не менее, это все еще не работает.

Как изменить приведенный выше код так, чтобы он работал на планшетах с "touchstart" вместо "mousedown"?

7 ответов

Решение

Вы должны явно потянуть touches объект вне события, он не содержит координаты напрямую. Посмотрите на вторую строку кода ниже.

Вот код, который я всегда использую, чтобы получить координаты касания / указателя:

    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;
    }

Поместите это в слушатель событий, который прослушивает любое или все эти события, и добавьте свой расчет смещения, и это должно сработать.

Ответ Кристофера Рида почти сработал для меня, но мне пришлось внести несколько корректировок, потому чтоoriginalEvent собственность не была частью event когда я тестировал в Google Chrome версии 81.0.4044.138 и Mozila Firefox версии 76.0.1.

Поскольку я нашел несколько ответов, которые напрямую используют event и другие, которые используют event.originalEventсвойство, я добавил проверку, чтобы использовать первое, если последнее не определено.

Так что вместо:

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

Я использовал:

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

Таким образом, полный ответ будет таким:

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;
}

Обычно вы используете, например, e.touches[0].clientX обрабатывать сенсорные события

Решение, не являющееся JQuery, при условии, что у вас есть следующий HTML

<div id="touchme" style="width: 200px; height: 200px; background: blue;">

И скрипт

document.getElementById("touchme").addEventListener("touchstart",
function clicked(e) {
    var br = document.getElementById("touchme").getBoundingClientRect();
    // x & y are relative to the clicked element
    var x = e.touches[0].clientX - br.left;
    var y = e.touches[0].clientY - br.top;
    console.log("x: " + x + " y: " + y);
});

Обратите внимание, что следующий скрипт обрабатывает только первый (из всех возможных) сенсорный ввод

PointerEvent поддерживает как мышь, так и сенсорное управление, начиная с IE 11.

Например, посмотрите Sortable.js.

Привязать события #L423

      el.addEventListener('pointerdown', handler);

Получите координаты #L574

      let touch = (evt.touches && evt.touches[0]) || (evt.pointerType && evt.pointerType === 'touch' && evt);
let clientX = (touch || evt).clientX;
let clientY = (touch || evt).clientY;

Попробуй это:

$(function(){

$('body').on('touchstart', function(e) {
  var offset = $("#element").offset();
  var t = e.targetTouches.length > 0 ? e.targetTouches.item(0) : e.touches.item(0); 
  var relativeX = t.pageX - offset.left;
  var relativeY = t.pageY - offset.top;
  console.log(relativeX+':'+relativeY);
  $(".position").val("afaf");
});

});

Если у вас есть встроенная прокрутка, вы должны сделать это следующим образом:

      const rect = event.target.getBoundingClientRect();
x = event.targetTouches[0].pageX - (rect.left + document.documentElement.scrollLeft);
y = event.targetTouches[0].pageY - (rect.top + document.documentElement.scrollTop);

Я адаптировал решение Domenico для перемещения камеры на ПК и мобильных устройствах для threeJS без управления орбитой:

      window.addEventListener("touchmove", function clicked(e) {
cursor.x = e.touches[0].clientX / sizes.width - 0.5
cursor.y = -(e.touches[0].clientY / sizes.height - 0.5)});
Другие вопросы по тегам