Javascript 消除移动 Safari 中点击事件的 300 毫秒延迟

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12238587/
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-23 07:28:51  来源:igfitidea点击:

Eliminate 300ms delay on click events in mobile Safari

javascriptjqueryjquery-mobilesafaritouch

提问by tim peterson

I've read that mobile Safari has a 300ms delay on click eventsfrom the time the link/button is clicked to the time the event fires. The reason for the delay is to wait to see if the user intends to double-click, but from a UX perspective waiting 300ms is often undesirable.

我读到移动 Safari从点击链接/按钮到事件触发有 300 毫秒的点击事件延迟。延迟的原因是等待看看用户是否打算双击,但从 UX 的角度来看,等待 300 毫秒通常是不可取的。

One solutionto eliminate this 300ms delay is to use jQuery Mobile "tap" handling. Unfortunately I'm not familiar with this framework and don't want to load some big framework if all I need is a line or two of code applying touchendin the right way.

消除这种 300 毫秒延迟的一种解决方案是使用 jQuery Mobile“点击”处理。不幸的是,我不熟悉这个框架,如果我需要的只是以touchend正确方式应用的一两行代码,我不想加载一些大框架。

Like many sites, my site has many click events like this:

像许多网站一样,我的网站有许多这样的点击事件:

$("button.submitBtn").on('click', function (e) {   
  $.ajaxSubmit({... //ajax form submisssion
});

$("a.ajax").on('click', function (e) {   
  $.ajax({... //ajax page loading
});

$("button.modal").on('click', function (e) {   
      //show/hide modal dialog
});

and what I'd like to do is to get rid of the 300ms delay on ALLthose click events using a single code snippet like this:

我想要做的是使用这样的单个代码片段摆脱所有这些点击事件的 300 毫秒延迟:

$("a, button").on('tap', function (e) {
 $(this).trigger('click');
 e.preventDefault();
});

Is that a bad/good idea?

这是一个坏/好主意吗?

采纳答案by NoNameProvided

Now some mobile browsers eliminate 300 ms click delay if you set the viewport. You don't need to use workarounds anymore.

现在,如果您设置视口,一些移动浏览器会消除 300 毫秒的点击延迟。您不再需要使用变通方法。

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

This is currently supported Chrome for Android, Firefox for Androidand Safari for iOS

这是目前支持Android版ChromeAndroid版FirefoxSafari浏览器适用于iOS

However on iOS Safari, double-tap is a scroll gesture on unzoomable pages. For that reason they can't remove the 300ms delay. If they can't remove the delay on unzoomable pages, they're unlikely to remove it on zoomable pages.

但是在 iOS Safari 上,双击是不可缩放页面上的滚动手势。出于这个原因,他们无法删除 300ms delay。如果他们不能在不可缩放的页面上消除延迟,他们就不太可能在可缩放的页面上消除它。

Windows Phonesalso retain the 300ms delay on unzoomable pages, but they don't have an alternative gesture like iOS so it's possible for them to remove this delay as Chrome has. You can remove the delay on Windows Phone using:

Windows Phone在不可缩放的页面上也保留了 300 毫秒的延迟,但它们没有像 iOS 那样的替代手势,因此它们可以像 Chrome 那样消除这种延迟。您可以使用以下方法消除 Windows Phone 上的延迟:

html {
-ms-touch-action: manipulation;
touch-action: manipulation;
}

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

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

UPDATE 2015 December

2015 年 12 月更新

Until now, WebKit and Safari on iOS had a 350ms delay before single taps activate links or buttons to allow people to zoom into pages with a double tap. Chrome changed this a couple of months ago already by using a smarter algorithm to detect that and WebKit will follow with a similar approach. The article gives some great insights how browsers work with touch gestures and how browsers can still get so much smarter than they are today.

到目前为止,iOS 上的 WebKit 和 Safari 在单击激活链接或按钮以允许人们通过双击放大页面之前有 350 毫秒的延迟。几个月前,Chrome 已经通过使用更智能的算法来检测这一点而改变了这一点,而WebKit 将采用类似的方法。这篇文章提供了一些很好的见解,浏览器如何处理触摸手势,以及浏览器如何仍然比现在更智能。

UPDATE 2016 March

2016 年 3 月更新

On Safari for iOS, the 350 ms wait time to detect a second tap has been removed to create a “fast-tap” response. This is enabled for pages that declare a viewport with either width=device-width or user-scalable=no. Authors can also opt in to fast-tap behavior on specific elements by using the CSS touch-action: manipulationas documented here(scroll down to the 'Styling Fast-Tap Behavior' heading) and here.

在 iOS 版 Safari 上,检测第二次点击的 350 毫秒等待时间已被删除,以创建“快速点击”响应。这适用于声明视口为 width=device-width 或 user-scalable=no 的页面。作者还可以通过使用此处touch-action: manipulation记录的 CSS (向下滚动到“样式化快速点击行为”标题)和此处来选择对特定元素进行快速点击行为。

回答by Jonathan

This plugin -FastClick developed by Financial Timesdoes it perfectly for you!

这个由金融时报开发的插件-FastClick完美地为您服务!

Make sure though to add event.stopPropagation();and/or event.preventDefault();directly after the click function, otherwise it might run twice as it did for me, i.e.:

确保在点击功能之后添加event.stopPropagation();和/或event.preventDefault();直接添加,否则它可能会像我一样运行两次,即:

$("#buttonId").on('click',function(event){
    event.stopPropagation(); event.preventDefault();
   //do your magic

});

回答by Michael Turnwall

i know this is old but can't you just test to see if "touch" is supported in the browser? Then create a variable that's either "touchend" or "click" and use that variable as the event that gets bound to your element?

我知道这是旧的,但你不能测试一下浏览器是否支持“触摸”?然后创建一个“touchend”或“click”变量并将该变量用作绑定到元素的事件?

var clickOrTouch = (('ontouchend' in window)) ? 'touchend' : 'click';
$('#element').on(clickOrTouch, function() {
    // do something
});

So that code sample checks to see if the "touchend" event is supported in the browser and if not then we use the "click" event.

因此,该代码示例会检查浏览器是否支持“touchend”事件,如果不支持,则使用“click”事件。

(Edit: changed "touchend" to "ontouchend")

(编辑:将“touchend”更改为“ontouchend”)

回答by tim peterson

I've come across a hugely popular alternative called Hammer.js(Github page)which I think is the best approach.

我遇到了一个非常流行的替代方案,称为 Hammer.js (Github 页面),我认为这是最好的方法。

Hammer.js is a more full-featured touch library (has many swipe commands) than Fastclick.js (most upvoted answer).

Hammer.js 是一个比 Fastclick.js(最受好评的答案)更全功能的触摸库(有很多滑动命令)。

Beware though:scrolling fast on mobile devices tends to really lock up the UI when you use either Hammer.js or Fastclick.js. This is a major problem if your site has a newsfeed or an interface where users will be scrolling a lot (would seem like most web apps). For this reason, I'm using neither of these plugins at the moment.

不过要注意:当您使用 Hammer.js 或 Fastclick.js 时,在移动设备上快速滚动往往会真正锁定 UI。如果您的网站有一个新闻源或一个用户会滚动很多的界面(看起来像大多数网络应用程序),这是一个主要问题。出于这个原因,我目前没有使用这些插件。

回答by ayke

Somehow, disabling zoom seems to disable this small delay. Makes sense, as double-tap isn't needed anymore then.

不知何故,禁用缩放似乎禁用了这个小延迟。有道理,因为那时不再需要双击。

How can I "disable" zoom on a mobile web page?

如何在移动网页上“禁用”缩放?

But please be aware of the usability impact this will have. It may be useful for webpages designed as apps, but shouldn't be used for more general-purpose 'static' pages IMHO. I use it for a pet project that needs low latency.

但请注意这将产生的可用性影响。它可能对设计为应用程序的网页有用,但不应用于更通用的“静态”页面恕我直言。我将它用于需要低延迟的宠物项目。

回答by Andreas K?berle

Unfortunately there is no easy way to do this. So just using touchstartor touchendwill leave you with other problems like someone starts scrolling when click on on a button for example. We use zeptofor a while, and even with this really good framework there are some issues that came up over the time. A lot of them are closed, but it seems is not a field of simple solution.

不幸的是,没有简单的方法可以做到这一点。因此,仅使用touchstarttouchend会给您带来其他问题,例如单击按钮时有人开始滚动。我们使用zepto有一段时间了,即使有了这个非常好的框架,随着时间的推移也会出现一些问题。他们中的很多都是封闭的,但这似乎不是一个简单的解决方案。

We have this solution to globally handle clicks on links:

我们有这个解决方案来全局处理链接点击:

   $(document.body).
    on('tap', 'a',function (e) {
      var href = this.getAttribute('href');
      if (e.defaultPrevented || !href) { return; }
      e.preventDefault();
      location.href= href;
    }).
    on('click', 'a', function (e) {
      e.preventDefault();
    });

回答by Jarda Pavlí?ek

I searched for an easy way without jquery and without fastclick library. This works for me:

我搜索了一种没有 jquery 和 fastclick 库的简单方法。这对我有用:

var keyboard = document.getElementById("keyboard");
var buttons = keyboard.children;
var isTouch = ("ontouchstart" in window);
for (var i=0;i<buttons.length;i++) {
    if ( isTouch ) {
        buttons[i].addEventListener('touchstart', clickHandler, false);         
    } else {
        buttons[i].addEventListener('click', clickHandler, false);          
    }
}

回答by theaws.blog

Just to provide some extra information.

只是为了提供一些额外的信息。

On iOS 10, <button>s on my page could not be triggered continuously. There was always a lag.

在 iOS 10 上,<button>我的页面上的 s 无法连续触发。总是有一个滞后。

I tried fastclick / Hammer / tapjs / replacing click with touchstart, all failed.

我试过 fastclick / Hammer / tapjs / 用 touchstart 替换 click,都失败了。

UPDATE: the reason seems to be that the button is too close to the edge! move it to near the center and lag gone!

更新:原因似乎是按钮离边缘太近了!把它移到靠近中心的地方,然后就没有了!

回答by Bruno Andrade

You're supposed to explicitly declare passive mode:

您应该明确声明被动模式

window.addEventListener('touchstart', (e) => {

    alert('fast touch');

}, { passive : true});

回答by Benjamin

In jQuery you can bind "touchend" event, witch trigger code inmediatly after tap (is like a keydown in keyboard). Tested on current Chrome and Firefox tablet versions. Don't forget "click" also, for your touch screen laptops and desktop devices.

在 jQuery 中,您可以绑定“touchend”事件,在点击后立即触发代码(就像键盘中的按键)。在当前的 Chrome 和 Firefox 平板电脑版本上测试。对于触摸屏笔记本电脑和台式设备,也不要忘记“单击”。

jQuery('.yourElements').bind('click touchend',function(event){

    event.stopPropagation();
    event.preventDefault();

 // everything else
});