92

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

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

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

$("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
});

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

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

这是一个坏/好主意吗?

4

10 回答 10

75

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

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

目前支持 Android 版 Chrome、Android 版FirefoxiOS版 Safari

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

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

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

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

2015 年 12 月更新

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

2016 年 3 月更新

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

于 2014-01-11T12:21:00.560 回答
43

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

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

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

});
于 2012-11-05T01:08:58.580 回答
17

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

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

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

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

于 2013-04-29T22:08:43.327 回答
12

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

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

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

于 2013-05-24T14:19:01.460 回答
2

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

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

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

于 2013-03-02T20:14:28.520 回答
1

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

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

   $(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();
    });
于 2012-09-02T18:56:41.803 回答
1

我搜索了一种没有 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);          
    }
}
于 2015-08-15T20:11:41.977 回答
1

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

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

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

	// everything else
});

于 2017-12-07T23:20:11.160 回答
0

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

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

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

更新:原因似乎是按钮太靠近边缘!将它移到中心附近并滞后消失!

于 2017-03-07T10:02:30.350 回答
0

你应该明确声明被动模式

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

    alert('fast touch');

}, { passive : true});
于 2017-08-15T21:23:41.613 回答