Mobile Safari - 当最后一次触摸结束时,“touchend”事件不会触发?

7
我试图捕捉的“手势”是在元素(其他或相同)已经有触摸时进行轻击。 因此,触摸(1)按下按钮,而触摸(2)则轻击选定的选项,触摸(1)释放并使按钮凹陷。
我遇到的问题在于最后一部分。 当我松开最后一个手指时,“touchend”事件没有被触发? 所以我无法使按钮凹陷?
另外,“touchend”事件总是具有touches.length = 0?
以下是一些代码,以便您了解我的意思。 我认为这可能是移动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>

请务必包含您的操作系统版本。在我的3.1.3版本中(第一代iPod touch),这个程序按预期工作:"touchstart 1","touchstart 2","touchend 1","touchend 0"。 - Glenn Maynard
当然抱歉。在iPad上的3.2.1版本,这个问题和其他一些问题似乎已经在4.2版本中得到了修复。 - ad rees
2个回答

3
我可以帮你解决一个问题,但我不知道为什么"touchend"事件在两个手指同时离开屏幕时不会触发。当我运行你上面的代码时,在iPhone 4上任何一个手指离开屏幕时,"touchend"事件都会触发。
1) 在iPhone上,“touchend”事件虽然有“touches”属性,但当最后一个手指离开屏幕时,它始终为空,因为“touches”代表当前触摸屏幕的手指,“touchend”事件只会在手指离开屏幕后触发。所以在“touchend”时,“e.touches.length”将始终为0,当最后一个手指抬起时。
2) 你可以通过使用“changedTouches”属性来访问“touchend”事件中哪些触摸操作已更改。这是有问题的,因为其行为不是非常一致的。
如果你用一个手指触摸屏幕,然后再用另一个手指触摸屏幕,然后再移开一只手指,可能会发生很多事情。
如果第二根手指离开屏幕时,第一根手指没有变化,那么你的事件对象在“touchend”中将具有“touches.length = 1”(仍在屏幕上的手指)和“changedTouches.length = 1”(离开屏幕的手指)。
然而,如果你在移开第二根手指时正在移动第一根手指(即使只是一点),那么在“touchend”时,你的事件对象将具有“touches.length = 1”(仍在屏幕上的手指)和“changedTouches.length = 2”(离开屏幕的手指+第一根手指的移动)。
我发现这篇文章非常有用: http://m14i.wordpress.com/2009/10/25/javascript-touch-and-gesture-events-iphone-and-android/

太棒了!在 Android 上的测试中,我发现没有像提到的那样的 event.touch 对象,但我建议在代码中支持触摸数组(event.touches 和 event.changedTouches),因为它们在 Android 和 iOS 上都很可靠。在我的情况下(只需要一个手指的 x 和 y 坐标),我先测试 changedTouches,然后是 touches,检查它们是否未定义并且长度 === 1,按照这个顺序。 - Chris Bosco

0

类型为touchend的TouchEvent,e.touches.length始终为0。

缺失的最后一个touchend事件可能取决于触摸目标。如果两个手指同时放开并且目标相同,则只会触发一个touchend事件,但它会在e.changedTouches对象中有两个触点。如果目标不同,则会看到两个touchend事件,每个事件都带有关联的触摸对象。

此外,最令人困惑的是,当您放开其中两个手指时,您将获得与放开两个手指相同的行为。然后,当剩余的手指移动时,它将触发另一个touchstart事件,并在touches中使用该手指的原始标识符。结果是,无法在touchend时告诉哪个触点已结束,直到任意时间(当剩余手指移动时)。

要验证这一点,您需要记录每个事件中的touchLists。 我找到的唯一解决方法是一个把touchstart事件存入缓存的技巧,隔半秒钟调用setInterval,然后希望剩余的手指已触发touchstart事件,以便我可以用来调节状态。天啊!


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