Javascript 在触摸式鼠标事件中检索相同的偏移量

Javascript 在触摸式鼠标事件中检索相同的偏移量,javascript,html,canvas,Javascript,Html,Canvas,您好,我正在尝试获取触摸事件的偏移量x,Y,它应该与鼠标事件的偏移量x相同。为此,我使用了以下代码: ev.offsetX = ev.targetTouches[0].pageX- canvasName.offsetLeft 我甚至尝试将触摸事件模拟为鼠标事件,但为此,我需要offsetX/Y,这在触摸事件中不可用。是否有任何方法可以计算触摸屏的偏移量X/Y?请帮助如果您的页面上有滚动,您应该使用鼠标事件(或pageX/pageY)的clientX/clientY属性 至于你的解决办法。可以

您好,我正在尝试获取触摸事件的偏移量x,Y,它应该与鼠标事件的偏移量x相同。为此,我使用了以下代码:

 ev.offsetX = ev.targetTouches[0].pageX- canvasName.offsetLeft

我甚至尝试将触摸事件模拟为鼠标事件,但为此,我需要offsetX/Y,这在触摸事件中不可用。是否有任何方法可以计算触摸屏的偏移量X/Y?请帮助

如果您的页面上有滚动,您应该使用鼠标事件(或
pageX
/
pageY
)的
clientX
/
clientY
属性

至于你的解决办法。可以使用
getElementById(canvasName).clientX来更正它

ev.offsetX = ev.targetTouches[0].pageX - getElementById(canvasName).clientX
canvasName.offsetLeft
是相对于其父级的
canvasName
的偏移量。因此,如果您想使用
offsetLeft
,您应该执行以下操作

var left = 0,
elem = getElementById(canvasName);

while(elem) {
  left = left + parseInt(elem.offsetLeft);
  elem = elem.offsetParent;         
}

ev.offsetX = ev.targetTouches[0].pageX - left
我用这个

var rect = e.target.getBoundingClientRect();
var x = e.targetTouches[0].pageX - rect.left;
var y = e.targetTouches[0].pageY - rect.top;

我知道这是一个老问题,但在谷歌的“offsetX触摸事件”中还是第一个。。在我做了研究之后,我最终使用了类似的东西

function getOffsetPosition(evt, parent){
    var position = {
        x: (evt.targetTouches) ? evt.targetTouches[0].pageX : evt.clientX,
        y: (evt.targetTouches) ? evt.targetTouches[0].pageY : evt.clientY
    };

    while(parent.offsetParent){
        position.x -= parent.offsetLeft - parent.scrollLeft;
        position.y -= parent.offsetTop - parent.scrollTop;

        parent = parent.offsetParent;
    }

    return position;
}

如果使用jQuery touchend事件,layerX和layerY属性提供相对的x和y,但不考虑转换。因此,我通过从css中获取变换比例值来手动应用变换

e=来自jQuery的touchend事件

parent=应用“transform”的父元素的jQuery对象。对我来说是
$(e.target.parentNode)

要使最后两行与触摸和单击事件兼容,请执行以下操作:

const offsetX = e.offsetX || layerX * currentScaleX;
const offsetY = e.offsetY || layerY * currentScaleY;
获取变换值的参考:

如果您使用的是Reactjs
onClick
,那么您可以通过:
e.nativeEvent.layerX
获得layerX和layerY值。由于某些原因,layerX和layerY在React touch事件中不可用。如果确实需要使用React
onTouchEnd

const rect = e.nativeEvent.target.getBoundingClientRect();       
const layerX = e.changedTouches[0].clientX - rect.left;
const layerY = e.changedTouches[0].clientY - rect.top;
const currentScale = 1 / parseFloat(parent.css('transform').match(/-?[\d\.]+/g)[0]);
const offsetX = layerX * currentScale;
const offsetY = layerY * currentScale;
注意:最好将转换的值存储在Redux中,而不是用jQuery获取它们。


这里最好的答案不适合我,在网页上滚动!这将更好地发挥作用:

var bcr = e.target.getBoundingClientRect();
var x = e.targetTouches[0].clientX - bcr.x;
var y = e.targetTouches[0].clientY - bcr.y;
我用它来解决我的问题。

我用它:

const {x, y, width, height} = e.target.getBoundingClientRect();
const offsetX = (e.touches[0].clientX-x)/width*e.target.offsetWidth;
const offsetY = (e.touches[0].clientY-y)/height*e.target.offsetHeight;

什么是
canvasName
?尝试使用
canvasName。clientX
canvasName是canvasstop的id!然后你需要做一些类似于
canvas=getElementById(canvasName)
的事情,然后你可以做
canvas.offsetLeft
对不起,我不能完全解释它,我已经做了getElementById的事情,我正在为鼠标事件获取正确的值,我只需要同样的触摸…我也在看你的解决方案我需要触摸事件中鼠标事件的offsetX值…clientX不适用于触摸事件这对转换(例如旋转)元素不起作用。offsetX在变换前给出元素的局部坐标系中的值;这不是。@tremby只做x/scaleRatio和y/scaleRatio。有没有理由认为这比@alex nikulin的顶级答案更有效?因为那个答案要简洁得多。@alex nikulin的答案没有考虑偏移量,我已经更新了我的答案,将我试图理解的内容包括了一个经过清理和更小的改编。getBoundingClientRect是一个计算量很大的工具,它还显示了您如何对特定用例有其他需求。在您经常调用它的情况下,考虑到它的使用性质,几乎每次都会使用它,您会注意到,找到一个不使用getBoundingClientRect()的答案,我真的很兴奋,但(不幸的是)我不认为这会更快。这与
getBoundingClientRect()
的计算基本相同,但使用js线程而不是本机线程。这太糟糕了,因为getBoundingClientRect()相当重。我只在touchstart上使用getBoundingClientRect()而不是touchmove,您可以在每次touchmove中存储要重用的值,因为您只需要在clientX/Y中进行更改,这将大大减少计算量。但我遇到的问题是,当你放大时,它似乎没有考虑到,我在iOS 14 Safari上。这与@alex nikulin?pageX/Y->clientX/Y接受的最热门答案有什么不同
var bcr = e.target.getBoundingClientRect();
var x = e.targetTouches[0].clientX - bcr.x;
var y = e.targetTouches[0].clientY - bcr.y;
const {x, y, width, height} = e.target.getBoundingClientRect();
const offsetX = (e.touches[0].clientX-x)/width*e.target.offsetWidth;
const offsetY = (e.touches[0].clientY-y)/height*e.target.offsetHeight;