【问题标题】:Understanding touch events了解触摸事件
【发布时间】:2013-01-07 08:25:08
【问题描述】:

我正在尝试使我的一些库与触摸设备一起使用,但我很难弄清楚它们是如何被支持的以及它们是如何工作的。

基本上,有5 touch events,但似乎移动浏览器之间只有在touchstart 事件上达成共识(duh)。我创建了一个fiddle 作为测试用例。

我已经在装有 Android 4 的 Galaxy Note 上对此进行了测试,但您也可以使用桌面浏览器查看链接。

我们的目标是尝试弄清楚如何处理轻按、双击和长按。没什么特别的。

基本上是这样的:

Android 股票浏览器 不会触发触摸事件。它只是尝试通过点击模拟鼠标点击,连续触发mousedownmouseupclick 事件,但双击只是放大和缩小页面。

Chrome for Android 会在手指触摸屏幕时触发 touchstart 事件。如果它发布得足够快,它会触发mousedownmouseuptouchend,最后是click 事件。

长按的情况下,大约半秒后它会在手指抬起时触发mousedownmouseup,以及touchend,最后没有click事件.

如果您移动手指,它会触发几次touchmove 事件,然后触发touchcancel 事件,之后什么都不会发生,甚至不会触发touchend 事件抬起手指。

双击会触发放大/缩小功能,但在事件方面它会触发组合 touchstart-touchevent 两次,而不会触发鼠标事件。

Firefox for Android 正确触发touchstart 事件,并且在短按触发mousedownmouseuptouchendclick 之后。

长按的情况下,它会触发mousedownmouseup,最后是touchend 事件。对于这些事情,Chrome 也是如此。

但是如果你移动你的手指,如果连续触发touchmove(正如人们所期望的那样)但它不会在手指离开时触发touchleave事件带有事件监听器的元素,当手指离开浏览器视口时不会触发touchcancel 事件。

对于双击,它的行为就像 Chrome。

Opera Mobile 与 Chrome 和 Firefox 一样,只需轻按一下,但长按会激活某种我真的想禁用的共享功能。如果您移动手指或双击,它的行为就像 Firefox。

Chrome 测试版通常用于短按,但在长按的情况下,它不再触发 mouseup 事件,仅触发 touchstart,然后在半秒后触发 mousedown ,然后在抬起手指时touchend。当手指移动时,现在它的行为就像 Firefox 和 Opera Mobile。

双击的情况下,缩小时不会触发触摸事件,而只会在放大时触发。

Chrome 测试版显示出最奇怪的行为,但我真的不能抱怨,因为它是测试版。

问题是:在最常见的触摸设备浏览器中,是否有一种简单且有效的方法来尝试检测短按、长按和双击?

很遗憾,我无法在带有 Safari 的 iOS 设备或适用于 Windows Phone 7/Phone 8/RT 的 IE 上对其进行测试,但如果你们中的一些人可以的话,我们将非常感谢您的反馈。

【问题讨论】:

标签: javascript mobile touch


【解决方案1】:

是的,您可以在touchstart 开始计时器并在touchend 结束计时器,然后从那里做出选择。

你也可以...比如说滑动,我的触发touchmove 你可以得到“手指”的坐标,看看我在touchend 被触发之前走了多少。

我不知道是否有任何比使用触摸事件库更简单的方法,但我想你可以很容易地为简单的“点击”、“双击”、“滑动”事件编写一个。

【讨论】:

  • 如果你仔细想想,并考虑上面浏览器的行为,你会承认这根本不容易。例如,如果您触摸一个元素,然后将手指移到该元素之外,然后抬起手指,这将不是有效的“点击”,但您无法检测到它,因为永远不会触发 touchleave。跨度>
  • 你说得很好,但是;使用适当的编码,例如我们,在 touchstart 捕获元素 e.target(我相信),它是否与 touchend 上的元素相等?如果不是,那么它不是一个有效的水龙头,它是一个陷阱。我并不是说编写一个库会很容易,但它并不是真的“难”,我会将它列为“中等”+如果它没有挑战性并且让我们返回 stackoverflow xD 有什么乐趣
  • 编写库对我来说不是问题,我觉得它具有挑战性、令人满意并且有些有趣。但是您的评论只是暗示了一个解决方案,但是您如何构建它呢?您将有关touchstart 事件的信息保存在哪里?如果同时触发第二个touchstart 事件(多点触控显示)怎么办?你如何处理长水龙头?使用setTimeout,但是如果手指同时离开元素怎么办?如果没有触发触摸事件,您如何检测它?等等……我当然会尝试,但我希望找到对触摸事件的深入分析。
  • 你不能在没有触发 touchend 事件的情况下触发第二个 touchstart 事件,因此你不能同时点击两次,所以没问题。您可以将信息保留在变量中并在 touchend 处重置它们
  • 这是不正确的,您可以在第一个 touchend 出现之前拥有第二个 touchstart。此外,再次考虑您的答案会得出这样的结论:它不会有帮助,因为touchend 事件的target 属性总是 等于触摸开始的元素,即使手指移到元素外!
【解决方案2】:

如果您还没有,我建议您阅读 Hammer.js 的源代码

https://github.com/hammerjs/hammer.js/blob/master/hammer.js

在 cmets 和代码之间大约 1400 行,有很棒的文档,代码很容易理解。

你可以看到作者是如何选择解决很多常见的触摸事件的:

按住、点击、双击、拖动、拖动开始、拖动结束、向上拖动、向下拖动、 向左拖动,向右拖动,滑动,向上滑动,向下滑动,向左滑动,向右滑动, 变换,transformstart,transformend,旋转,捏,捏, pinchout, touch (手势检测开始), release (手势检测 结束)

我认为阅读源代码后,您将对触摸事件的工作原理以及如何识别浏览器能够处理的事件有更好的理解。

http://eightmedia.github.io/hammer.js/

【讨论】:

  • 一段有趣的代码,看起来相当完整和广泛。我可能需要一些时间来分析它。
【解决方案3】:

这是我对 Android 4.3 上触摸和鼠标事件的最新观察

Opera、Firefox 和 Chrome 似乎有标准行为

  1. 滑动时(touchstart-touchmove-touchend):

    1. 没有鼠标事件(不包括鼠标悬停)触发。
    2. 仅当 touchstart 和 touchend 出现在同一元素上时才会触发鼠标悬停。 (touchstart-touchmove-touchend-mouseover)
    3. 如果在 touchstart 上阻止默认设置:默认滑动行为不起作用。鼠标事件触发不会发生任何变化。
  2. 点按(touchstart-touchend):

    1. 所有鼠标事件 mouseover-mousemove-mousedown-mouseup-click 在延迟后触发
    2. 如果在 touchstart 上阻止默认设置:仅触发鼠标悬停。

Android 默认浏览器有一些非标准行为

  1. 鼠标悬停在 touchstart 之前触发,这意味着鼠标悬停总是触发。
  2. 所有鼠标事件都会在 Tap 时触发,即使默认设置在 touchstart 时被阻止。

【讨论】:

    【解决方案4】:

    有一个非常棒的资源https://patrickhlauke.github.io/touch/tests/results/ 详细介绍了数量惊人的浏览器中的事件顺序。它似乎也定期更新(2016 年 9 月,最后一次更新是 2016 年 8 月)。

    要点是,基本上所有事情都会触发mouseover 和相关事件;大多数还触发触摸事件,通常mouseover 之前完成(到达touchend),然后继续到click(除非更改页面内容会取消此操作)。谢天谢地,这些尴尬的例外情况相对较少(第 3 方 android 浏览器和黑莓 playbook)。

    该链接资源的详细程度令人印象深刻,以下是众多操作系统、设备和浏览器测试中的前三个示例:

    总结一些关键点:

    移动浏览器

    • 所有列出的浏览器都会在第一次点击时触发mouseover。只有部分 Windows Phone 浏览器会在第二次点击时触发它。
    • 全部触发click。如果mouseover 更改页面,它没有指定取消click(我相信大多数人都会这样做)
    • 大多数浏览器在touchstarttouchend 之后触发mouseover。这包括 iOS7.1 Safari、原生 Android、Chrome、Opera 和 Firefox for Android,以及一些(并非所有 Windows 手机浏览器)
    • 几个 Windows Phone 浏览器(所有 Windows 8 / 8.1 和一个 10 版本)和几个第 3 方 Android 浏览器(Dolphin、Maxathon、UC)触发 mouseover 之后 touchstart 和 @ 987654337@.
    • 只有 Blackberry Playbook 在 touchstarttouchend 之间触发 mouseover
    • 只有 Opera Mini 和 Puffin(第 3 方 Android 浏览器)缺少 touchstarttouchend

    桌面浏览器

    • 桌面 Chrome 和 Opera 的最新版本的行为与其移动版本类似,touchstarttouchend,然后是 mouseover
    • Firefox 和 Microsoft 浏览器(IE touchstart 和 touchend 事件。
    • 没有关于 Mac 的数据,但考虑到 Mac 触摸屏界面的稀缺性,大概没有 Ma 浏览器支持 touchstarttouchend

    在结合辅助技术的浏览器上还有大量数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      • 2011-05-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多