如何捕获touchend的坐标?

44

我想在touchend事件上捕获触摸坐标,但是获取的是undefined。 touchstart事件可以正常工作,但同样的概念在touchend上失败了。 我使用mousedownmouseup构建了这个代码,并且那个效果很好。

我漏掉了什么?

div.addEvent("touchstart", function (event) {
    event.preventDefault(); // to avoid scrolling
    span.innerHTML = event.page.x;
});
div.addEvent("touchend", function (event) {
    span.innerHTML = event.page.x;
});

FIDDLE

6个回答

41

您需要在touchmove事件中存储值,并在touchend中读取它。

var lastMove = null;

// Save the touchstart to always have a position
div.addEvent('touchstart', function(event) {
  lastMove = event;
});

// Override with touchmove, which is triggered only on move
div.addEvent('touchmove', function(event) {
  lastMove = event;
});

这么简单吗?谢谢!为什么在mouseup上不需要mousemove就能工作? - Rikard
1
我不知道。我本来以为touchend事件会包括它结束的位置,但也许有一些特殊情况无法给出,比如当触摸退出区域时(即使之前的值已知,也无法给出当前值)。而mouseup则始终在区域内,而mouseout则用于在退出区域时使用。 - adrenalin
3
正确的原因似乎是触摸事件会存储当前的触摸信息,当触摸结束时,就不再有当前的触摸信息了。 - adrenalin
14
这个解决方案来自于谷歌搜索的touchend事件,但我通常在touchend事件中使用event.changedTouches [0] .pageX来获取坐标,例如:http://jsfiddle.net/YrQjH/3/ - Darryl_Lehmann
2
很抱歉,但这个答案有点不正确,因为只有当触摸实际移动时才会触发move事件。一个简单的“点击式”的触摸将触发touchstart,然后是touchend,而永远不会是touchmove。所以,是的,你需要在touchmove中存储位置,但大多数情况下也需要在touchstart中存储位置,以防没有拖动。在这种情况下,要存储的是X、Y位置,而不是事件。 - FlorianB

39
我一直在查看规范,4个触摸事件都继承自touchEvent对象,该对象有3个列表属性,保存关于事件时所有触点(屏幕上的每个手指)的信息。每个列表根据以下标准保存触点:

changedTouches:保存已经离开目标元素表面的触点。

touches:保存所有当前的触点。

targetTouch:保存所有当前在目标元素表面内的触点。

事件touchend在changedTouches中保存了手指离开屏幕的位置,而在其他列表中没有保存任何内容,因此如果需要访问这些内容,应使用event.changedTouches[event.changedTouches.length-1],这将返回一个具有pageX和pageY属性的触点对象,用于保存坐标信息。
整行代码如下:

span.innerHTML = event.changedTouches[event.changedTouches.length-1].pageX;
我至今无法理解的是,如果在touchEvent对象中没有坐标属性,为什么您可以在touchstart和touchmove事件中使用它们,而不是在touchend事件中使用。也许实现添加了这个快捷方式,或者我读错了。


这正是我所需要的。在某些设备上,如果移动更像是轻触,则不会触发touchmove事件。因此,从touchmove内部存储事件失败了。这种方法每次都有效。 :) - Ed Fryed
它是 e.originalEvent.changedTouches[...]。 - rttmax
在 touchend 处理程序中找到的事件对象中,originalEvent 未定义。 - David Villamizar

14

touchend事件中,应该使用changedTouches而不是touches

div.addEvent("touchstart", function (event) {
    event.preventDefault(); // to avoid scrolling
    span.innerHTML = event.pageX;
});
div.addEvent("touchend", function (event) {
    span.innerHTML = event.changedTouches[0].pageX;
});

3

虽然这个问题没有要求使用jQuery,但如果你需要一种jQuery的替代方案,请尝试这段代码。它适用于所有最新版本的jQuery。

$(document).on('touchstart', '.className', function (e) {
    console.log(e.originalEvent.touches[0].pageX);
});
$(document).on('touchend', '.className', function (e) {
    console.log(e.originalEvent.changedTouches[0].pageX);
});

您可以选择省略 'originalEvent',并在仅使用JS脚本和不支持jQuery/浏览器的情况下使用 'changedTouches'。

1
touchStart(event) {
  this.startX = event.touches[0].pageX;
},
touchEnd(event) {
  this.endX = event.changedTouches[0].pageX;
},

1
请问您能否提供更多的信息来解释您的代码?只需要一两句话就可以了。 - Frits

0

我建议这个方法非常好用,可以恢复与传统计算机相同的事件属性...

if(!('ontouchstart' in document.documentElement)){

Object.onmouseup = function(e){
      your code....
}

}else{

Object.ontouchend = function(e){
e = e.changedTouches[e.changedTouches.length-1];
      Your code....
}

}

非常容易管理。

*要管理您的代码,请在PC上使用Google Chrome,在控制台模式下它可以捕获TOUCH事件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接