30

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

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

我什至尝试将触摸事件模拟为鼠标事件,但为此我需要 offsetX/Y,它在触摸事件中不可用。有什么方法可以为触摸计算 offsetX/Y 吗?请帮忙

4

8 回答 8

36

我用这个

var rect = e.target.getBoundingClientRect();
var x = e.targetTouches[0].pageX - rect.left;
var y = e.targetTouches[0].pageY - rect.top;
于 2015-11-17T12:16:43.680 回答
8

在滚动网页上,这里的最佳答案对我不起作用!这将更好地工作:

var bcr = e.target.getBoundingClientRect();
var x = e.targetTouches[0].clientX - bcr.x;
var y = e.targetTouches[0].clientY - bcr.y;

我用它来解决我的问题。

于 2020-03-03T23:37:11.873 回答
5

我知道这是一个古老的问题,但在谷歌的“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;
}
于 2017-05-15T05:48:38.320 回答
1

如果您在页面上滚动,您应该使用鼠标事件(或/ )的clientX/属性。clientYpageXpageY

至于你的解决方案。它可以通过使用来纠正getElementById(canvasName).clientX

ev.offsetX = ev.targetTouches[0].pageX - getElementById(canvasName).clientX

canvasName.offsetLeftcanvasName相对于它的父级偏移。因此,如果您想使用offsetLeft,您应该执行以下操作

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

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

ev.offsetX = ev.targetTouches[0].pageX - left
于 2013-06-16T07:55:24.200 回答
1

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

e = 来自 jQuery 的 touchend 事件

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

const layerX = e.originalEvent.layerX;
const layerY = e.originalEvent.layerY;
const currentScale = 1 / parseFloat(parent.css('transform').match(/-?[\d\.]+/g)[0]);

const offsetX = layerX * currentScale;
const offsetY = layerY * currentScale;

要使最后两行与触摸和单击事件兼容:

const offsetX = e.offsetX || layerX * currentScaleX;
const offsetY = e.offsetY || layerY * currentScaleY;

抓取transform值参考: 直接使用jquery获取transform的css值

如果您使用的是 Reactjs onClick,那么您可以通过以下方式获取 layerX 和 layerY 值:e.nativeEvent.layerX。由于某种原因 layerX 和 layerY 在 React 触摸事件中不可用。如果你确实需要使用 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 获取它们。

于 2017-09-07T22:00:55.907 回答
1

归功于https://stackoverflow.com/a/11396681/1997890

function recoverOffsetValues(e) {
    var rect = e.target.getBoundingClientRect();
    var bodyRect = document.body.getBoundingClientRect();
    var x = e.originalEvent.changedTouches[0].pageX - (rect.left - bodyRect.left);
    var y = e.originalEvent.changedTouches[0].pageY - (rect.top - bodyRect.top);

    return [x, y];
}
于 2019-02-03T16:25:53.577 回答
0

我用这个:

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;
于 2021-03-29T16:50:45.733 回答
0

您可以使用PointerEvent代替触摸事件,它们具有更多属性。例如:

div.addEventListener('pointermove', console.log);

输出:

isTrusted: true
altKey: false
altitudeAngle: 1.5707963267948966
azimuthAngle: 0
bubbles: true
button: -1
buttons: 1
cancelBubble: false
cancelable: true
clientX: 203
clientY: 483
composed: true
ctrlKey: false
currentTarget: null
defaultPrevented: false
detail: 0
eventPhase: 0
fromElement: null
height: 23
isPrimary: true
layerX: 203
layerY: 177
metaKey: false
movementX: 0
movementY: -1
offsetX: 203
offsetY: 177.6875
pageX: 203
pageY: 483
pointerId: 9
pointerType: "touch"
pressure: 1
relatedTarget: null
returnValue: true
screenX: 734
screenY: 621
shiftKey: false
sourceCapabilities: null
tangentialPressure: 0
tiltX: 0
tiltY: 0
toElement: null
twist: 0
type: "pointermove"
which: 0
width: 23
x: 203
y: 483
[[Prototype]]: PointerEvent

使用示例:MDN:捏缩放手势

于 2021-12-29T05:04:15.677 回答