【问题标题】:Mobile Safari - "touchend" event not firing when last touch is removed?移动 Safari - 删除最后一次触摸时未触发“touchend”事件?
【发布时间】:2013-11-23 09:24:37
【问题描述】:

我试图捕捉的“手势”是一个点击,当但仅当一个元素(其他或相同)已经触摸它时。因此,触摸 (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”。
  • 当然很抱歉。 3.2.1 在 iPad 上。这和其他一些似乎已在 4.2 中修复

标签: javascript ipad cordova mobile-safari


【解决方案1】:

我可以帮你解决一个问题,但我不知道为什么当我的两根手指离开屏幕时“touchend”没有触发,当我在上面运行你的代码时,当任一手指离开屏幕时“touchend”就会触发屏幕(在 iPhone 4 上)

1) 虽然 iPhone 的 "touchend" javascript 事件确实具有 "touches" 属性,但当最后一根手指离开屏幕时它总是为空,因为 iPhone 的 "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 然后触摸未定义且长度 === 1,按此顺序
【解决方案2】:

touchend 类型的 TouchEvent 的 e.touches.length 总是为 0

缺少的最后一次触摸结束事件可能取决于触摸的目标。如果两个手指同时抬起并且都具有相同的目标,那么只有一个触摸端会触发,但它会在 e.changedTouches 对象中同时进行两次触摸。如果目标不同,那么您将看到两个 touchend 事件,每个事件在 changedTouches 对象中都有关联的触摸。

此外,最令人费解的是,当您抬起两个手指中的一个时,您会得到与同时抬起两个手指相同的行为。然后,当剩下的手指移动时,它将触发另一个 touchstart,并在触摸中使用该手指的原始标识符。结果是在任意时间之后(当剩余的手指移动时),在触摸结束时无法判断哪个触摸已经结束。

要验证这一点,您需要记录每个事件中的 touchList。 我发现的唯一解决方法是缓存 touchstart 事件,setInterval 半秒,然后希望剩余的手指触发了我可以用来协调状态的 touchstart。好悲伤!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-06
    • 1970-01-01
    • 2021-12-10
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多