zoukankan      html  css  js  c++  java
  • 移动端click事件延迟300ms到底是怎么回事,该如何解决?

    不管在移动端还是PC端,我们都需要处理用户点击,这个最常用的事件。但在touch端click事件响应速度会比较慢,在较老的手机设备上会更为明显(300ms的延迟)。

    问题由来

    这要追溯至 2007 年初。苹果公司在发布首款 iPhone 前夕,遇到一个问题:当时的网站都是为大屏幕设备所设计的。于是苹果的工程师们做了一些约定,应对 iPhone 这种小屏幕浏览桌面端站点的问题。

    这当中最出名的,当属双击缩放(double tap to zoom),这也是会有上述 300 毫秒延迟的主要原因。双击缩放,顾名思义,即用手指在屏幕上快速点击两次,iOS 自带的 Safari 浏览器会将网页缩放至原始比例。

    那么这和 300 毫秒延迟有什么联系呢?

    假定这么一个场景。用户在 iOS Safari 里边点击了一个链接。由于用户可以进行双击缩放或者双击滚动的操作,当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击操作。因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕。

    鉴于iPhone的成功,其他移动浏览器都复制了 iPhone Safari 浏览器的多数约定,包括双击缩放,几乎现在所有的移动端浏览器都有这个功能。之前人们刚刚接触移动端的页面,在欣喜的时候往往不会care这个300ms的延时问题,可是如今touch端界面如雨后春笋,用户对体验的要求也更高,这300ms带来的卡顿慢慢变得让人难以接受。

    那么我们该如何解决这个问题,可能有的同学会想到touchstart事件,这个事件响应速度很快啊,如果说开发的界面上面可点击的地方很少,要么用户滑动下手指就触发touchstart事件,也会让人崩溃的。大家可以参考如下的几种方法。

    粗暴型:禁用缩放

    <meta name="viewport" content="width=device-width, user-scalable=no">
    关键是 user-scalable = no。
    这个属于简单粗暴型的,虽然看似完美,但有一个致命的缺陷,当你必须完全禁用缩放来达到目的时候,就傻眼了,只有特定场景下的交互界面,此方案才可行,其它大多数情况,此法都不可行。 另外:Chrome 开发团队不久前宣布,在 Chrome 32 这一版中,他们将在包含 width=device-width 或者置为比 viewport 值更小的页面上禁用双击缩放。当然,没有双击缩放就没有 300 毫秒点击延迟。

    指针事件 (Pointer Events)

    指针事件最初由微软提出,现已进入 W3C 规范的候选推荐标准阶段 (Candidate Recommendation)。这个草案规范旨在使用一个单独的事件模型,对所有输入类型,包括鼠标 (mouse)、触摸 (touch)、触控 (stylus) 等,进行统一的处理。

    比如用css设置-ms-touch-action: none,那么对应的元素在被点击之后,浏览器不会启动缩放操作,也就避免了这个300ms延迟,但目前只有IE10+支持,目前touch开发的重点在safari和chrome,因此你懂的,此方案目前兼容性不好,不过chrome表示会在未来版本中支持的。

    指针事件 (使非IE也支持)

    上面也说道touch-action: none是一个办法,那么其它浏览器不支持怎么办呢?下面的几个类库是关于这方面的,感兴趣的可以去研究下:

    1.Google的Polymer
    2.微软的 HandJS
    3.@Rich-Harris 的 Points

    touch-action: none这种方案虽然可以解决这个问题,但影响的面比较广,不是单纯的来解决300ms延时问题的,有可能会带来性能和其它操作上的隐患,慎用。

    FastClick:闪亮登场

    FastClick是FT Labs专门为解决移动端浏览器 300 毫秒点击延迟问题所开发的一个轻量级的库。简而言之,FastClick 在检测到 touchend 事件的时候,会通过 DOM 自定义事件立即触发一个模拟 click 事件,并把浏览器在 300 毫秒之后真正触发的click事件阻止掉。

    FastClick 的使用方法非常简单,在 window load 事件之后,在body上调用FastClick.attach()即可。

    window.addEventListener( "load", function() {
    FastClick.attach( document.body );
    }, false );
    attach方法虽可在更具体的元素上调用,直接绑定到body上可以确保整个应用都能受益。当 FastClick 检测到当前页面使用meta设置了user-scalable=no或者 touch-action 属性的解决方案时,会静默退出。可以说,这是真正的跨平台方案出来之前一种很好的变通方案。

    就目前而言,FastClick 非常实际地解决 300 毫秒点击延迟的问题,唯一的缺点可能也就是该脚本的文件尺寸 (尽管它只有10kb)。如果你连这10kb都接受不了的话,那么移动端类库 jQuery和zepto.js都支持tap事件来解决这个问题,尽管它们的响应速度比FastClick慢一些。

    正是因为有这些解决方案,那么首先还是挑选眼前更合适的吧,毕竟以后会不会出新标准来解决这个问题,谁都不知道,理论上来说FastClick也是属于替代方案,希望有一天touch 端的开发可以不走pc的路,让本来都苦逼的前端雪上加霜。

  • 相关阅读:
    LeetCode 769. Max Chunks To Make Sorted
    LeetCode 845. Longest Mountain in Array
    LeetCode 1059. All Paths from Source Lead to Destination
    1129. Shortest Path with Alternating Colors
    LeetCode 785. Is Graph Bipartite?
    LeetCode 802. Find Eventual Safe States
    LeetCode 1043. Partition Array for Maximum Sum
    LeetCode 841. Keys and Rooms
    LeetCode 1061. Lexicographically Smallest Equivalent String
    LeetCode 1102. Path With Maximum Minimum Value
  • 原文地址:https://www.cnblogs.com/shenjp/p/6433646.html
Copyright © 2011-2022 走看看