【问题标题】:Is disabling all click events at first touchstart event a good idea?在第一个 touchstart 事件中禁用所有点击事件是个好主意吗?
【发布时间】:2014-12-10 10:00:59
【问题描述】:

由于touchstart、tap和300ms延迟点击之间的冲突,制作一个好的快速响应网站相对困难。

当然vclick 应该解决这些问题,但他们似乎也无法完全解决这些问题。来自文档:

警告:谨慎使用 vclick

在触控设备上谨慎使用 vclick。基于 Webkit 的浏览器 在大约 300 毫秒后合成 mousedown、mouseup 和 click 事件 touchend 事件被调度。合成鼠标的目标 事件是在它们被调度时计算的,并且基于 触摸事件的位置,在某些情况下, 实现特定的启发式,导致不同的目标 不同设备甚至不同操作系统版本上的计算 相同的设备。这意味着原始元素中的目标元素 触摸事件可能与 合成鼠标事件。

我们建议在任何时候使用 click 而不是 vclick 触发有可能改变下面的内容 在屏幕上触摸的点。这包括页面转换和 其他可能导致 屏幕移动或内容被完全替换。

现在我正在考虑做一些更简单的事情。每当触发 touchstart 事件时,我都知道这是肯定的触摸设备。我只是禁用所有点击事件,然后开始监听 touchstart(或点击)事件only。忽略 300 毫秒的延迟点击事件。

当然也有带有鼠标触摸的设备,但同时使用这些的人对我来说似乎是少数。

这是个好主意,还是我的想法中遗漏了什么?

【问题讨论】:

  • 我认为使用打开屏幕来检测触摸事件是否可用是可以的,但在 UX 方面有一些缺点。例如,如果用户触摸屏幕但没有移开手指,则您可能已经触发了该事件,并且正如您所建议的那样,聆听点击事件会更好。为此,我个人使用自定义点击/触摸包装器。它检测触摸开始(如果可用)并相应地管理触摸开始/移动/结束。
  • 触摸屏笔记本电脑正在成为 Windows 世界的常态,因此您需要注意不要为这些用户破坏您的网站。

标签: javascript mobile touch


【解决方案1】:

首先……是什么让您说同时使用触摸和鼠标输入的人是少数?

现在在 Android 上使用 <meta name="viewport" content="width=device-width"> 时,300 毫秒的点击延迟已经消失了一段时间。不幸的是can't be removed on iOS,因为它是几乎没有人知道的不可缩放页面上的滚动手势。

我想说最好的方法仍然是同时支持鼠标和触摸输入,尽管 iOS 设备上有 300 毫秒的延迟。假设用户只使用一次触摸输入是很危险的。

想象一个用户愉快地使用鼠标进行导航。他们看到了一些有趣的东西,想仔细看一下,所以他们使用触摸手势放大,突然之间鼠标点击不再起作用。这对我来说听起来很糟糕。

我刚想起一个关于检测鼠标用户的interesting discussion。也许它会帮助您以不同的方式看待事物。

【讨论】:

  • 鼠标和触摸的人是少数(此时)是相当有常识的。至少在荷兰这里。我确切知道有 0 个人的屏幕支持触摸并且通常与鼠标一起使用。据我所知,几乎每个人都有智能手机,几乎每个人都有台式机或普通笔记本电脑(没有触摸)。并不意味着它们不存在。只是意味着他们是少数。比如我也不支持的IE7用户。
  • ps。 300 毫秒延迟,因为我无法忍受这个应用程序的原生体验。
【解决方案2】:

是的,老实说,这是明智的做法。这已被证明是一个相当困难的问题,当你仍然将它与一些非常糟糕的移动设备引起的兼容性问题结合起来时,这些问题甚至不符合标准,它很快就会变成一场你无法获胜的战斗。我们采用了接近此的解决方案,并意识到设备质量差可能会出现问题。但毕竟,您无法满足所有人的需求,而且使用分布往往偏向于那些遵循标准的设备(现在)。

另请注意,您无需等待第一次 touchstart 发生。相反,您可以在 DOM 准备好后执行此技巧并相应地绑定事件。

var isTouchDevice = 'ontouchstart' in document.documentElement;

复制自KevBurnsJr's answer

您可能已经知道,您可以绑定到所有类型的事件,然后在进入回调时检查事件实际使用的类型

event.type

祝你好运!

【讨论】:

  • 您好 Sanfor,感谢您的回答。问题是检测触摸能力与真正知道用户将使用触摸不同。
  • 确实如此,因此,您仍然可以使用 event.type 来纠正基于 isTouchDevice 所做的假设。
  • 'ontouchstart' in document.documentElement 并不意味着它是仅触控设备。它只检测对 Touch Evens API 的支持。您不能也不应该仅根据触控功能假设用户将使用什么。
【解决方案3】:

按照您的建议,基于单个 touchstart 禁用 所有 点击事件是个坏主意。虽然同时使用两个指针或触摸不是常见的用例。防止鼠标/笔和触摸的双重使用不是向前兼容的方法。

当你说:“忽略 300 毫秒的延迟点击事件。”

我认为您对click 做出了错误的假设。您仍然必须以一种或另一种方式合成点击。 touchstart 本身不是点击操作。假设点击发生在touchend,而不是touchstart。以下是在移动设备上及早检测点击背后的原理:https://developers.google.com/mobile/articles/fast_buttons

如果您正在寻找快速点击,您可能需要查看 fastclick 脚本或 github 上的其他 fastclick 脚本,而不是 vclicks

【讨论】:

    【解决方案4】:

    为了避免人们同时使用触摸屏和鼠标且反应灵敏,我建议在 JQuery 中这样做,它对我来说已经足够好了:

    $elem.on('click touchstart', function(e){
       var $self = $(this);
       if(e.type == 'touchstart'){ 
          $self.mouseenter(); //fire events you still need 
          e.preventDefault();
       }
       /* your code */
    });
    

    根据我的经验,这比通过设备保持点击事件的延迟和一些危险的行为要好,但也有不便之处。

    在我测试的 iPad 上,它避免了在第一次点击时触发悬停事件然后在第二次点击时触发单击事件的情况,但似乎当您在元素边框附近点击而不是 touchstart 时触发点击事件,一定要牢记。

    此外,它似乎不适用于 'tap' 事件,当然是因为 JQuery 还没有很好地处理它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多