了解触摸事件


80

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

基本上有5个touch事件,但似乎移动浏览器之间仅在touchstart事件(duh)上存在共识。我创建了一个小提琴作为测试用例。

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

目的是试图弄清楚如何处理龙头,双击和长龙头。没有什么花哨。

基本上就是这样:

Android的股票浏览器不火的触摸事件。它只是试图模仿鼠标点击,水龙头,射击mousedownmouseupclick事件连续,但双水龙头只是在进出塔页面缩放。

当手指触摸屏幕时,Chrome浏览器Android版会触发touchstart事件。如果它的发布很快,它触发那么mousedownmouseuptouchend最后click事件。

长按的情况下,大约半秒钟后会发出声音,mousedown并且mouseup,并且touchend在手指松开时click结束。

如果您移动手指,它会触发一个touchmove事件两次,然后触发一个touchcancel事件,此后什么也不会发生,即使touchend抬起手指也不会发生任何事件。

双击触发器/缩小变焦功能,但事件明智它触发组合touchstart-touchevent两次,没有鼠标事件被解雇。

火狐为Android正确触发该touchstart事件,并在短击火灾的情况下mousedownmouseuptouchendclick之后。

在的情况下,长按,它触发mousedownmouseup最后touchend事件。这些方面与Chrome相同。

但是,如果你移动你的手指,如果火灾touchmove汽车无(作为一个可以预期),但它不火的touchleave事件当手指离开与事件侦听器的元素,并且不火的touchcancel当手指得到浏览器窗口的出事件。

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

Opera Mobile只需短按一下即可完成Chrome和Firefox的功能,但是如果长按,则会激活某种我确实要禁用的共享功能。如果您动手指或双击,它的行为就像Firefox。

Chrome beta版通常会在短按时执行操作,但在长按时不会再触发该mouseup事件,只是touchstart,然后mousedown在半秒钟后,再touchend在手指松开时触发。手指移动后,现在的行为就像Firefox和Opera Mobile。

如果双击,则在放大时不触发触摸事件,而仅在放大触发。

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

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

太糟糕了,我无法在具有Safari或Windows Phone 7 / Phone 8 / RT的IE的iOS设备上对其进行测试,但是如果您可以的话,我们将非常感谢您的反馈。


1
您是否尝试过Tocca.js?gianlucaguarini.github.io/Tocca.js它可以在任何类型的设备上启用所有丢失的触摸事件,并且大约只有1kb
Gianluca Guarini 2013年

Answers:


26

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

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

注释和代码之间大约有1400行,有大量的文档,并且代码易于理解。

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

按住,点击,双击,拖动,dragstart,dragend,dragup,dragdown,dragleft,dragright,swipe,swipeup,swipedown,swipeleft,swiperight,transform,transformstart,transformend,旋转,捏,pinchin,pinchout,触摸(手势检测开始) ,释放(手势检测结束)

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

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


有趣的代码片段,似乎相当完整和广泛。我可能需要一些时间来分析它。
MaxArt 2013年

9

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

要点是,基本上所有的触发器mouseover和相关事件都是如此。大多数也会触发触摸事件,通常会在触摸事件发生touchend之前完成(到达)mouseover,然后继续进行click(除非更改页面内容会取消此操作)。幸运的是,那些尴尬的例外相对罕见(第三方Android浏览器和黑莓剧本)。

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

在此处输入图片说明

总结一些关键点:

手机浏览器

  • 所有列出的浏览器都mouseover在第一次点击时触发。仅某些Windows Phone浏览器会在第二次点击时触发它。
  • 全部触发clickclick如果mouseover更改页面,它没有指定哪个取消(我相信大多数都可以)
  • 大多数浏览器mouseovertouchstart和之后触发touchend。其中包括iOS7.1 Safari,原始Android,Chrome,Opera和Firefox for Android,以及某些(并非所有Windows手机浏览器)
  • 多个Windows Phone浏览器(所有Windows 8 / 8.1和一个10版本)和多个第三方Android浏览器(Dolphin,Maxathon,UC)mouseover touchstart之后触发touchend
  • 只有Blackberry Playbookmouseovertouchstart和之间触发touchend
  • 仅Opera Mini和Puffin(第三方Android浏览器)缺少touchstarttouchend

桌面浏览器

  • 合理高达桌面版Chrome和Opera的最新版本的行为和移动的同行,touchstarttouchend随后mouseover
  • Firefox和微软浏览器(IE <= 11和边缘的许多版本)不会触发任何touchstarttouchend事件。
  • Macs上没有数据,但大概没有Ma浏览器支持,touchstart并且touchendMac触摸屏界面稀缺。

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


3

是的,您可以在计时器处启动touchstart并结束计时器,然后touchend从那里进行选择。

您也可以做...比如说滑动,我的触发touchmove可以使您获得“手指”的齿形,并查看touchend触发之前我走了多少。

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


1
如果考虑到这一点,并考虑上述浏览器的行为,您将承认这并不容易。例如,如果您触摸某个元素,然后将手指移到该元素之外,然后抬起手指,那将不是有效的“敲击”,但是您将无法检测到它,因为touchleave它永远不会触发。
MaxArt 2013年

你说的很对,但是;通过适当的编码(例如我们e.target),可以在touchstart上捕获元素(我相信),它是否与touchend上的元素相等?如果否,那么这不是有效的分接头,而是陷阱。我并不是说对库进行编码很容易,但是并不是真正的“难”,我会把它列为“中”,如果它不具有挑战性并且使我们重返stackoverflow xD,那么有什么好玩的
Alexandru Calin

对我来说,对库进行编码不是什么问题,我觉得它充满挑战,令人满足并且有些有趣。但是您的评论只是暗示一种解决方案,但是您如何构建它呢?您在哪里保存有关touchstart事件的信息?如果touchstart同时触发第二个事件(多点触控显示)怎么办?您如何处理长水龙头?使用setTimeout,但是如果手指同时离开该元素怎么办?如果没有触发触摸事件,如何检测到它?依此类推...当然,我会尝试一下,但我希望能找到一种深入的触摸事件分析。
MaxArt 2013年

您不能在不触发touchend事件的情况下触发第二个touchstart事件,因此您不能有两次轻敲,所以没有问题。您可以将信息保留在变量中,并在触摸时重置它们
Alexandru Calin

这是不正确的,您可以touchstart在第一次touchend出现之前先等待一秒钟。此外,再次考虑您的答案会得出结论,它无济于事,因为事件的target属性始终等于触摸开始的元素,即使手指移到元素之外!touchend
MaxArt 2013年

3

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

Opera,Firefox和Chrome似乎具有标准行为

  1. 滑动时(触摸开始-触摸-移动-触摸结束):

    1. 不会触发任何鼠标事件(包括mouseover)。
    2. 仅当在同一元素上发生touchstart和touchend时,才会触发Mouseover。(touchstart-touchmove-touchend-mouseover)
    3. 如果在touchstart上阻止了默认设置:默认的滑动行为将不起作用。鼠标事件触发未发生任何变化。
  2. 在Tap(touchstart-touchend)上:

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

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

  1. 鼠标悬停在touchstart之前触发,这意味着鼠标悬停总是触发。
  2. 即使在touchstart上禁用了默认设置,所有鼠标事件也会在Tap上触发。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.