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

Javascript 消除mobile Safari中点击事件的300毫秒延迟,javascript,jquery,jquery-mobile,safari,touch,Javascript,Jquery,Jquery Mobile,Safari,Touch,我已经读到,从点击链接/按钮到触发事件。延迟的原因是等待用户是否打算双击,但从用户体验的角度来看,等待300ms通常是不可取的 为了消除这种300ms延迟,可以使用jQuery移动“tap”处理。不幸的是,我不熟悉这个框架,如果我只需要一两行代码以正确的方式应用touchend,我不想加载一些大框架 与许多网站一样,“我的网站”也有许多类似的点击事件: $("button.submitBtn").on('click', function (e) { $.ajaxSubmit({...

我已经读到,从点击链接/按钮到触发事件。延迟的原因是等待用户是否打算双击,但从用户体验的角度来看,等待300ms通常是不可取的

为了消除这种300ms延迟,可以使用jQuery移动“tap”处理。不幸的是,我不熟悉这个框架,如果我只需要一两行代码以正确的方式应用
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
});
我想做的是用一个代码片段消除所有点击事件的300ms延迟,如下所示:

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

这是个坏主意/好主意吗

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

我们有这个解决方案,可以在全球范围内处理链接点击:

   $(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();
    });
这对你来说太完美了

确保添加
event.stopPropagation()和/或
事件.preventDefault()直接在单击功能之后,否则它可能会运行两次,即:

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

});

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


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

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

var clickOrTouch = (('ontouchend' in window)) ? 'touchend' : 'click';
$('#element').on(clickOrTouch, function() {
    // do something
});
因此,代码示例将检查浏览器中是否支持“touchend”事件,如果不支持,则使用“click”事件

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

我遇到了一个我认为是最好的方法

与Fastclick.js(多数被选中的答案)相比,Hammer.js是一个功能更全面的触摸库(有许多滑动命令)


不过要小心:当您使用Hammer.js或Fastclick.js时,在移动设备上快速滚动往往会真正锁定UI。如果你的网站有一个新闻提要或一个用户会经常滚动的界面(看起来像大多数web应用程序),这是一个主要问题。出于这个原因,我现在不使用这两个插件

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

<meta name="viewport" content="width=device-width, user-scalable=no">
资料来源:

2015年12月更新

到目前为止,iOS上的WebKit和Safari在单次点击激活链接或按钮之前有350毫秒的延迟,允许用户通过双击放大页面。Chrome在几个月前已经改变了这一点,它使用了一种更智能的算法来检测和处理这些问题。这篇文章提供了一些关于浏览器如何使用触摸手势的深刻见解,以及浏览器如何比现在更智能

2016年3月更新


在Safari for iOS上,检测第二次点击的350毫秒等待时间已被删除,以创建“快速点击”响应。这对于声明具有宽度=设备宽度或用户可伸缩性=否的视口的页面是启用的。作者还可以使用CSS
touch action:manipulation
(如文档所述)选择特定元素上的快速点击行为(向下滚动到“设置快速点击行为样式”标题)而且。

我寻找了一种没有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);          
    }
}
var-keyboard=document.getElementById(“键盘”);
var按钮=keyboard.children;
var isTouch=(“窗口中的ontouchstart”);

对于(var i=0;i,只是为了提供一些额外的信息

在iOS 10上,我的页面上的
s无法连续触发。始终存在延迟

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

更新:原因似乎是按钮离边缘太近了!将其移动到靠近中心的位置,然后延迟消失!

您应该明确声明被动模式:

在jQuery中,你可以绑定“touchend”事件,点击后在中间位置触发代码(就像键盘上的一个按键)。在当前的Chrome和Firefox平板电脑版本上进行测试。对于你的触摸屏笔记本电脑和桌面设备,也不要忘记“单击”

jQuery('.yourElements').bind('click touchend',函数(事件){
event.stopPropagation();
event.preventDefault();
//其他一切

})
@非常感谢,这可能会奏效………显然,从用户体验的角度来看,这并不好。”我会对这个假设持谨慎态度。@OliverMoran,谢谢你的更正,我刚刚编辑了那句话,请看上面的问题。。可能是一个解决方案:-@Andreas,谢谢,所以你主张不要使用我发布的常规
tap
解决方案,并在元素基础上分解
tap
事件?不,这不是重点oint不是试图自己构建一个
tap
解决方案。我会更新我的答案。-@Andreas,谢谢你的回答,很多点击事件都是AJAX,所以默认事件已经被阻止了。你介意更新你的答案来处理这个问题吗?看来我的一般
tap
解决方案在这方面看起来和你的一样案例?谢谢,我喜欢这种简单的方式。我希望其他人能对其可能存在的缺陷表示赞同。touchend事件不能取代click事件,因为@Andreas Köberle在他的回复中解释了这一点。例如,如果你滚动鼠标,手指停在按钮上,它就会变为tri
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);          
    }
}
window.addEventListener('touchstart', (e) => {

    alert('fast touch');

}, { passive : true});