使用 JavaScript 确定平板电脑上的触摸位置

问题描述 投票:0回答:7

我有一个名为“element”的对象。如果有人触摸平板电脑,我想返回触摸位置相对于对象的 x 和 y 坐标,即。 e.对象的左上角坐标为 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”的平板电脑上运行?

javascript position touch tablet touchstart
7个回答
33
投票

更新:请参阅下面Daniel Lavedonio de Lima的答案

您必须显式地将

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

将其放入事件侦听器中,侦听任何或所有这些事件并添加偏移量计算,这应该可以工作。


26
投票

Christopher Reid 的回答几乎对我有用,但我必须做一些调整,因为当我在 Google Chrome 版本 81.0.4044.138 和 Mozila Firefox 版本 76.0.1 中进行测试时,

originalEvent
属性不是
event
的一部分.

由于我发现一些直接使用

event
的答案和其他使用
event.originalEvent
属性的答案,我添加了一个检查以使用第一个,如果后者是 undefined

所以代替:

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

我用过:

const { touches, changedTouches } = e.originalEvent ?? e;
const touch = touches[0] ?? changedTouches[0];

所以完整的答案就变成了:

if(e.type.includes(`touch`) {
    const { touches, changedTouches } = e.originalEvent ?? e;
    const touch = touches[0] ?? changedTouches[0];
    x = touch.pageX;
    y = touch.pageY;
} else if (e.type.includes(`mouse`)) {
    x = e.clientX;
    y = e.clientY;
}

3
投票

通常您会使用例如

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

请注意,以下脚本仅处理第一个(所有可能的)触摸输入


3
投票

PointerEvent支持鼠标和触摸。

例如,让我们看看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;

1
投票

试试这个:

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

});

0
投票

我改编了Domenico解决方案,在没有轨道控制的情况下在PC和移动设备上移动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)});

0
投票

如果你有一些内置的滚动条,你应该按如下方式操作:

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);
© www.soinside.com 2019 - 2024. All rights reserved.