ChatGPT解决这个技术问题 Extra ChatGPT

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

从单击链接/按钮到触发事件的时间,我已经阅读了 mobile Safari has a 300ms delay on click events。延迟的原因是等待查看用户是否打算双击,但从 UX 角度来看,等待 300 毫秒通常是不可取的。

One solution 消除这 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();
});

这是一个坏/好主意吗?

@Pointy 谢谢,这可能只是工作......
“......从用户体验的角度来看,这显然不是很好。”我会对这个假设保持警惕。
@OliverMoran,感谢您的更正,我刚刚编辑了那句话,请参阅上面的问题..
可能是一个解决方案:stackoverflow.com/a/12969739/1491212

r
robocat

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

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

目前支持 Android 版 Chrome、Android 版 Firefox 和 iOS 版 Safari

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

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 will follow with a similar approach改变了这一点。这篇文章提供了一些很棒的见解,浏览器如何使用触摸手势,以及浏览器如何仍然比现在更智能。

2016 年 3 月更新

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


实际上,WP 有触摸事件:stackoverflow.com/questions/13396297/…
是的,正如我在帖子中所写的那样,它由 -ms-touch-action 控制。
从主页(独立)运行应用程序时,iOS 上仍然存在问题。如果有人找到了一个体面的解决方法,那将是非常受欢迎的
将触摸动作值设置为操作最接近所需的性能,但正如@MiguelGuardo 之前所说,一旦将网页作为独立应用程序添加到 iOS 的主屏幕,效果就会丢失。
可能有人可以破解 UIWebView - stackoverflow.com/questions/55155560/…
J
Jonathan

This plugin -FastClick developed by Financial Times 完美为您服务!

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

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

});

如果您使用的是 jquery mobile(无论如何是 1.3.2 版),这并不完美,它会破坏面板小部件 github.com/jquery/jquery-mobile/issues/6440 的关闭
那 event.stopPropagation() 正是我首先来到这个页面的原因。完美运行,谢谢!
@Jonathan fastclick 仅在有延迟问题的触摸设备上发挥其魔力(否则为 automatically bypassed )。但是,只需添加 stopPropagation & preventDefault 在每次点击事件之后,可能会对所有浏览器中的所有事件处理程序产生不必要的副作用。
M
Michael Turnwall

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

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

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

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


谢谢,我喜欢这个简单。我希望其他人能够指出它可能存在的陷阱。
由于@Andreas Köberle 在回复中的解释,touchend 事件无法替换点击事件。例如,如果您滚动并且手指停在按钮上,它将触发链接...
这是一个很棒的轻量级解决方案,而不必为了摆脱延迟而包含一个庞大的附加库。希望我能在这个上投票 5 次! (只要你不担心滚动场景!)
对于支持触摸和点击事件的计算机/浏览器,这是一个糟糕的解决方案。
有些设备同时支持触摸和点击事件,您希望它们都在不同的情况下触发。我们遇到过这样的情况:一些带有鼠标的 Windows 或 android 平板电脑显然会在您点击某物时触发点击事件,但它也会在您点击时触发触摸事件。这意味着你必须听这两个事件。作为一个额外的复杂因素,一些设备会在你点击时合成一个点击事件,所以在这些设备上同时监听可能会导致你的事件处理程序触发两次,除非你很小心。
t
tim peterson

我遇到了一个hugely popular alternative called Hammer.js (Github page),我认为这是最好的方法。

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

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


不要使用 Hammerjs。它有一些严重的问题,例如:github.com/EightMedia/hammer.js/issues/388 github.com/EightMedia/hammer.js/issues/366 至少在它们得到修复之前不要使用它
C
Community

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

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

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


A
Andreas Köberle

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

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

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

-@Andreas,谢谢,所以您主张不要使用我发布的通用 tap 解决方案并逐个元素地分解 tap 事件?
不,那不是重点。关键是不要尝试自己构建tap解决方案。我会更新我的答案。
-@Andreas,感谢您的回答,许多点击事件都是 AJAX,因此默认事件已被阻止。你介意更新你的答案来处理这个问题吗?在这种情况下,我的一般 tap 解决方案似乎与您的解决方案相同?
J
Jarda Pavlíček

我搜索了一种没有 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);          
    }
}

B
Benjamin

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

jQuery('.yourElements').bind('click touchend',function(event){ event.stopPropagation(); event.preventDefault(); // 其他一切 });


d
dz902

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

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

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

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


B
Bruno Andrade

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

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

    alert('fast touch');

}, { passive : true});