javascript 移动 Safari - 删除最后一次触摸时不会触发“touchend”事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3666929/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mobile Safari - "touchend" event not firing when last touch is removed?
提问by ad rees
The "gesture" I'm trying to capture is a tap when but only when an element (other or same) already has a touch on it. So, touch (1) presses the button down while touch (2) taps to selected options, touch (1) releases and button is depressed.
我试图捕捉的“手势”是轻按,但仅当元素(其他或相同的)已经对其进行了触摸时。因此,触摸 (1) 按下按钮,而触摸 (2) 轻触所选选项,触摸 (1) 释放并按下按钮。
The problem I'm having is with the last bit. The "touchend" event is not being fired when I release the last finger? So I have no way of depressing the button?
我遇到的问题是最后一点。当我松开最后一根手指时没有触发“touchend”事件?所以我没有办法按下按钮?
..also the "touchend" event always has touches.length = 0?
..还有“touchend”事件总是touches.length = 0?
Here is some code so you can see what I mean. I think this may be a bug in mobile safari?
这是一些代码,所以你可以明白我的意思。我认为这可能是移动 Safari 中的错误?
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Multi-touch problem</title>
<style>
#touchpane{
width:900px;
height:500px;
background-color:#333;
}
</style>
</head>
<body>
<div id="touchpane" click="void();"></div>
<script>
var tp = document.getElementById("touchpane");
tp.addEventListener('touchstart', function(e){
e.preventDefault();// to stop copy and paste
console.log("touchstart " + e.touches.length );
}, false)
tp.addEventListener('touchend', function(e){
console.log("touchend " + e.touches.length );
// not called when last finger removed?
}, false)
tp.addEventListener('touchcancel', function(e){
console.log("touchcancel");
}, false)
</script>
</body>
</html>
回答by JoeDuncan
I can help you with one problem, but I don't know why the "touchend" isn't firing when both fingers leave the screen, when I run your code above, the "touchend" fires when either finger leaves the screen (on an iPhone 4)
我可以帮你解决一个问题,但我不知道为什么当两个手指离开屏幕时“touchend”没有触发,当我运行上面的代码时,当任一手指离开屏幕时“touchend”触发(在一部 iPhone 4)
1) While the "touchend" javascript event for iPhone does have the "touches" property, it's always going to be empty when the last finger leaves the screen, because "touches" for the iPhone represents fingers currently touching the screen, and "touchend" only fires aftera finger leaves the screen. So on "touchend" "e.touches.length" will always be 0 when the last finger is lifted.
1) 虽然 iPhone 的 "touchend" javascript 事件确实有 "touches" 属性,但当最后一根手指离开屏幕时它总是为空的,因为 iPhone 的 "touches" 代表当前正在触摸屏幕的手指,而 "touchend" " 仅在手指离开屏幕后触发。因此,当最后一个手指抬起时,“touchend”“e.touches.length”将始终为 0。
2) You can access which touches have changed in the "touchend" event by using the "changedTouches" property. This is problematic because it's behaviour is not very consistent.
2)您可以使用“changedTouches”属性访问“touchend”事件中哪些触摸发生了变化。这是有问题的,因为它的行为不是很一致。
If you touch the screen with one finger, then another, and then you remove one finger, a number of things could happen.
如果您用一根手指触摸屏幕,然后用另一根手指触摸屏幕,然后移开一根手指,可能会发生许多事情。
If you when you have removed the second finger, nothing has changed about the first finger, your event object in "touchend" will have "touches.length = 1" (the finger still on the screen) and "changedTouches.length = 1" (the finger that left the screen).
如果您移除第二根手指后,第一根手指没有任何变化,则“touchend”中的事件对象将具有“touches.length = 1”(手指仍在屏幕上)和“changedTouches.length = 1” (离开屏幕的手指)。
However, if you are moving the first finger (even a bit) when you remove the second finger, then on "touchend" your event object will have "touches.length = 1" (the finger still on the screen) and "changedTouches.length = 2" (the finger that left the screen + the movement of the first finger).
但是,如果您在移开第二根手指时移动第一根手指(甚至一点),那么在“touchend”上,您的事件对象将具有“touches.length = 1”(手指仍在屏幕上)和“changedTouches.length = 1”(手指仍在屏幕上)。长度 = 2"(离开屏幕的手指 + 第一根手指的移动)。
I found this article very helpful:
我发现这篇文章很有帮助:
http://m14i.wordpress.com/2009/10/25/javascript-touch-and-gesture-events-iphone-and-android/
http://m14i.wordpress.com/2009/10/25/javascript-touch-and-gesture-events-iphone-and-android/
回答by tschubring
TouchEvent of the type touchend always have e.touches.length of 0
touchend 类型的 TouchEvent 的 e.touches.length 总是为 0
The missing last touchend event could be dependent on the targets of the touches. If both fingers lift at the same time AND both have the same target then only one touchend will fire, but it will have both touches in the e.changedTouches object. If the targets are different then you will see two touchend events, each with the associated touch in the changedTouches object.
丢失的最后一个 touchend 事件可能取决于触摸的目标。如果两个手指同时抬起并且都有相同的目标,那么只有一个 touchend 会触发,但它会在 e.changedTouches 对象中同时进行两个触摸。如果目标不同,那么您将看到两个 touchend 事件,每个事件都在 changedTouches 对象中具有关联的触摸。
Furthermore, and most puzzling, is that when you lift one of two fingers you will get the same behavior as if you had lifted both. Then when the remaining finger moves it will fire another touchstart, with that finger's original identifier in the touches. The result is that there is no way to tell at the time of the touchend which touch has ended until after an arbitrary amount of time (when the remaining finger moves).
此外,最令人费解的是,当您抬起两个手指中的一个时,您会得到与同时抬起两个手指时相同的行为。然后当剩下的手指移动时,它将触发另一个 touchstart,在触摸中使用该手指的原始标识符。结果是直到任意时间量(当剩余的手指移动时)之后,才能在 touchend 时判断哪个触摸已经结束。
To verify this you need to document the touchLists in each event. The only workaround I found is a cludge where I cache the touchstart events, setInterval for half a second, then hope that the remaining finger has fired a touchstart I can use to reconcile the state. Good Grief!
要验证这一点,您需要记录每个事件中的 touchLists。我发现的唯一解决方法是缓存 touchstart 事件,setInterval 半秒,然后希望剩下的手指触发了一个 touchstart,我可以用它来协调状态。好悲伤!

