Javascript 300ms 延迟移除:使用 fastclick.js 与使用 ontouchstart

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27173272/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-22 23:49:00  来源:igfitidea点击:

300ms delay removal: using fastclick.js vs using ontouchstart

javascriptjquerycordovafastclick

提问by frenchie

I'm using regular jQuery and I have an event handler that looks like this:

我正在使用常规 jQuery,并且我有一个如下所示的事件处理程序:

$('#someID').on({

   click: SomeFunction

}, '.SomeClass');

This will produce a 300ms delay on the click event and I'm looking to remove this delay. What's the difference between rewriting this code like that:

这将在点击事件上产生 300 毫秒的延迟,我希望消除此延迟。像这样重写这段代码有什么区别:

$('#someID').on({

   'touchstart': SomeFunction

}, '.SomeClass');

and using an external library like Fastclick.js?

并使用像Fastclick.js这样的外部库?

回答by Andrew

I work for the Financial Times and head up the team that created Fastclick.js.

我在《金融时报》工作并领导创建 Fastclick.js 的团队。

In principle, all Fastclick does is bind to the touchendevent and fire a clickevent on the same element. However, there are many edge cases, traps and pitfalls, all of which we have discovered, worked around and baked into fastclick. For example:

原则上,Fastclick 所做的只是绑定到touchend事件并click在同一元素上触发事件。然而,有许多边缘情况、陷阱和陷阱,我们已经发现、解决了所有这些问题并融入了 fastclick。例如:

  • If you move your finger during the touch, it's a swipe or other kind of gesture, so we should not react
  • If you touch with more than one finger at a time, we should not react
  • If you touch a text field, the control needs to gain focus as well as receive a click event
  • Some controls require a native click to operate (for security), so we should allow selective opting-out of Fastclick
  • Some browsers already support fast clicking when viewport sizing defaults to device-width. We should not activate Fastclick behaviour at all in these user agents.
  • 如果您在触摸过程中移动手指,则是滑动或其他类型的手势,因此我们不应做出反应
  • 如果您一次用多个手指触摸,我们不应该做出反应
  • 如果您触摸文本字段,则控件需要获得焦点并接收单击事件
  • 一些控件需要原生点击操作(为了安全),所以我们应该允许选择性退出 Fastclick
  • 当视口大小默认为 时,某些浏览器已经支持快速单击device-width。我们根本不应该在这些用户代理中激活 Fastclick 行为。

Since Fastclick is 1% basic premise and 99% edge cases, there are lots of alternatives that are smaller, including probably one that you could write yourself. But many people prefer the reassurance that comes with using a well tested library.

由于 Fastclick 是 1% 的基本前提和 99​​% 的边缘情况,因此有很多较小的替代方案,其中可能包括您可以自己编写的替代方案。但是许多人更喜欢使用经过良好测试的库带来的保证。

Note that we use touchendand not touchstartbecause A) a click is not triggered until you lift your finger from the mouse button or trackpad, so touch should mirror that behaviour, and B) until you end the touch we don't yet know if you plan on moving your finger while it's in contact with the screen, which would be a gesture, swipe or scroll rather than a click.

请注意,我们使用touchend而不是touchstart因为 A) 在您将手指从鼠标按钮或触控板上移开之前不会触发点击,因此触摸应该反映该行为,并且 B) 直到您结束触摸我们还不知道您是否计划在手指与屏幕接触时移动手指,这将是手势、滑动或滚动,而不是单击。

Hope that helps.

希望有帮助。

回答by Truong Hong Thi

touchstarthappens at the time your finger touches the element while clickwon't fire until you release your finger (touchend) on the same element. If you touch, move your finger out of the element, then release, no clickevent occurs. However, in that case, touchstart does occur.

touchstart发生在您的手指触摸元素时,而click不会触发,直到您在同一元素上松开手指(touchend)。如果触摸,将手指移出元素,然后松开,则不会发生单击事件。但是,在这种情况下,touchstart 确实会发生。

Because you tag Cordova, I assume it is a Cordova hybrid app for mobile.
1. On Android since 2.3.x, 300ms is removed if you disable zoom:

因为你标记了Cordova,所以我假设它是一个用于移动的 Cordova 混合应用程序。
1. 自 2.3.x 起在 Android 上,如果禁用缩放,300ms 将被删除:

<meta name="viewport" content="width=device-width, user-scalable=no" />

2. On Android since 4.4.3 (whose webview is Chrome 33), 300ms is removed if you specify that the page is mobile-optimized:

2. 从 4.4.3 开始的 Android(其 webview 是 Chrome 33),如果您指定页面是移动优化的,则删除 300 毫秒:

<meta name="viewport" content="width=device-width" />
  1. On IE10+, use CSS to remove that delay:

    -ms-touch-action: manipulation; /* IE10 /
    touch-action: manipulation; /
    IE11+ */

  2. On iOS, you cannot use viewportto disable 300ms delay

  1. 在 IE10+ 上,使用 CSS 来消除延迟:

    -ms-touch-action:操纵;/* IE10 /
    触摸动作:操作;/
    IE11+ */

  2. 在 iOS 上,您不能使用视口禁用 300 毫秒延迟

Therefore, to make sure the 300ms is removed, I usually use a tap library for tap. For example: tappy(tap only), zepto touch(tap, swipe - good if your site already uses zepto), hammer.js(various gestures), depending on your needs. Those tap events do not suffer from the 300ms problem.

因此,为了确保删除 300ms,我通常使用 tap 库进行 tap。例如:tappy(仅限点击)、zepto touch(点击、滑动 - 如果您的网站已经使用 zepto,很好)、hammer.js(各种手势),具体取决于您的需求。这些点击事件不受 300 毫秒问题的影响。

FastClick.js should be OK though I did not try it yet.

FastClick.js 应该没问题,虽然我还没有尝试过。

回答by Hyman He

Andrew gives the correct answer.

安德鲁给出了正确的答案。

In general,

一般来说,

"touchstart"will be triggered when we perform "click","swipe","scroll" etc. However, as you know, what we want to capture is "click".

当我们执行“点击”、“滑动”、“滚动”等操作时会触发“touchstart”。但是,如您所知,我们要捕获的是“点击”。

What FastClick.js does is to define a rule for "click". For example, we could set the condition below as a "click":

FastClick.js 所做的是为 "click" 定义一个规则。例如,我们可以将下面的条件设置为“点击”:

During time between "touchstart" and "touchend" is 200ms, in "touchmove", we find no distance has been moved.

“touchstart”和“touchend”之间的时间为200ms,在“touchmove”中,我们发现没有移动距离。

The same, we could set the condition below as a "scroll":

同样,我们可以将下面的条件设置为“滚动”:

During "touchstart" and "touchend", in "touchmove", we find distance has been moved on y axis but no x axis moving happens.

在“touchstart”和“touchend”期间,在“touchmove”中,我们发现y轴上的距离已经移动,但x轴没有移动。

回答by AAhad

To get rid of 300msdelay, here are two options:

为了摆脱300ms 的延迟,这里有两个选项:

Option 1:

选项1:

By default, there will be about 300msdelay for the click event on webview, which results in a very slow response/performance when click on a button. You can try to override the click event with the ‘tap'event in jQuery Mobile to remove the delay: (Source: IBM)

默认情况下,webview上的单击事件会有大约300 毫秒的延迟,这会导致单击按钮时响应/性能非常慢。您可以尝试使用jQuery Mobile 中的“tap”事件覆盖单击事件以消除延迟:(来源:IBM

$('btnId').on('tap', function(e) {
     e.stopImmediatePropagation();
     e.preventDefault();
     ...
});

Option 2:Interesting one

选项 2:有趣的一个

By default JQuery Mobile CSS itselfhas introduced a long delay - I mean some places 300ms or 350ms or 225ms. These delays can be optimized. I too have modified the default CSS and reduced the long delay from 350msto 100msfor page transitionand it was really great.

默认情况下,JQuery Mobile CSS本身引入了很长的延迟——我的意思是在某些地方 300 毫秒或 350 毫秒或 225 毫秒。这些延迟可以优化。我也修改了默认CSS和减少从较长时间的延迟350毫秒100毫秒页面转换,这是真正伟大的。

Search in the Jquery Mobile CSS : animation-duration

在 Jquery Mobile CSS 中搜索:animation-duration

JQuery Mobile 1.2.0

jQuery 移动版 1.2.0

In some places delay is set to: -webkit-animation-duration:350ms;-moz-animation-duration:350mswhile other places delay is: -webkit-animation-duration:225ms;-moz-animation-duration:225ms

在某些地方延迟设置为:-webkit-animation-duration:350ms;-moz-animation-duration:350ms而其他地方延迟是:-webkit-animation-duration:225ms;-moz-animation-duration:225ms

The latest version on github:

github上的最新版本:

.in {
    -webkit-animation-timing-function: ease-out;
    -webkit-animation-duration: 350ms;
    -moz-animation-timing-function: ease-out;
    -moz-animation-duration: 350ms;
    animation-timing-function: ease-out;
    animation-duration: 350ms;
}
.out {
    -webkit-animation-timing-function: ease-in;
    -webkit-animation-duration: 225ms;
    -moz-animation-timing-function: ease-in;
    -moz-animation-duration: 225ms;
    animation-timing-function: ease-in;
    animation-duration: 225ms;
}

Check this github code:

检查这个github代码

Now it's up to you which delay you want to optimize, like click, page transition, flip, slide etc. and accordingly just modify the default delay time with your own desired delay time.

现在由您决定要优化哪个延迟,例如单击、页面转换、翻转、滑动等,因此只需使用您自己所需的延迟时间修改默认延迟时间即可。

In this way there is NOneed of an extra library

这样有需要一个额外的库

回答by TechWisdom

You may not use FastClick.js nowadays:

你现在可能不会使用 FastClick.js:

Note: As of late 2015 most mobile browsers - notably Chrome and Safari - no longer have a 300ms touch delay, so fastclick offers no benefit on newer browsers, and risks introducing bugs into your application. Consider carefully whether you really need to use it.

注意:截至 2015 年底,大多数移动浏览器(尤其是 Chrome 和 Safari)不再有 300 毫秒的触摸延迟,因此 fastclick 对较新的浏览器没有任何好处,并且有可能将错误引入您的应用程序。仔细考虑您是否真的需要使用它。

(Taken from: https://github.com/ftlabs/fastclickdocs)

(取自:https: //github.com/ftlabs/fastclickdocs)

回答by TechWisdom

If you go to a site that isn't mobile optimised, it starts zoomed out so you can see the full width of the page. To read the content, you either pinch zoom, or double-tap some content to zoom it to full-width. This double-tap is the performance killer, because with every tap we have to wait to see if it might become a double-tap, and that wait is 300ms. Here's how it plays out:

如果您访问的网站未针对移动设备进行优化,它会开始缩小,以便您可以看到页面的整个宽度。要阅读内容,您可以捏缩放,或双击某些内容将其缩放至全角。这种双击是性能杀手,因为每次点击我们都必须等待,看看它是否会变成双击,而等待时间为 300 毫秒。这是它的表现:

  • touchstart
  • touchend
  • Wait 300ms in case of another tap
  • click
  • 触摸启动
  • 触摸端
  • 等待 300 毫秒,以防再次点击
  • 点击

This pause applies to click events in JavaScript, but also other click-based interactions such as links and form controls.

这种暂停适用于 JavaScript 中的点击事件,但也适用于其他基于点击的交互,例如链接和表单控件。

http://updates.html5rocks.com/2013/12/300ms-tap-delay-gone-away

http://updates.html5rocks.com/2013/12/300ms-tap-delay-gone-away

Fastclick.js solve problem related if user didn't want to click on element and just decided to scroll.

Fastclick.js 解决了用户不想点击元素而只是决定滚动的相关问题。