从单击链接/按钮到触发事件的时间,我已经阅读了 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();
});
这是一个坏/好主意吗?
现在,如果您设置视口,一些移动浏览器会消除 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)来选择对特定元素进行快速点击行为。
This plugin -FastClick developed by Financial Times 完美为您服务!
确保在点击函数之后直接添加 event.stopPropagation();
和/或 event.preventDefault();
,否则它可能会像我一样运行两次,即:
$("#buttonId").on('click',function(event){
event.stopPropagation(); event.preventDefault();
//do your magic
});
fastclick
仅在有延迟问题的触摸设备上发挥其魔力(否则为 automatically bypassed )。但是,只需添加 stopPropagation
& preventDefault
在每次点击事件之后,可能会对所有浏览器中的所有事件处理程序产生不必要的副作用。
我知道这很旧,但你不能测试一下浏览器是否支持“触摸”吗?然后创建一个“touchend”或“click”变量并将该变量用作绑定到您的元素的事件?
var clickOrTouch = (('ontouchend' in window)) ? 'touchend' : 'click';
$('#element').on(clickOrTouch, function() {
// do something
});
因此,该代码示例检查浏览器是否支持“touchend”事件,如果不支持,则使用“click”事件。
(编辑:将“touchend”更改为“ontouchend”)
我遇到了一个hugely popular alternative called Hammer.js (Github page),我认为这是最好的方法。
Hammer.js 是一个比 Fastclick.js(最受好评的答案)功能更全面的触摸库(有许多滑动命令)。
但请注意:当您使用 Hammer.js 或 Fastclick.js 时,在移动设备上快速滚动往往会真正锁定 UI。如果您的网站有一个新闻源或用户会经常滚动的界面(看起来像大多数网络应用程序),这将是一个主要问题。出于这个原因,我目前没有使用这些插件。
不知何故,禁用缩放似乎禁用了这个小延迟。有道理,因为那时不再需要双击。
How can I "disable" zoom on a mobile web page?
但请注意这将产生的可用性影响。它可能对设计为应用程序的网页有用,但不应该用于更通用的“静态”页面恕我直言。我将它用于需要低延迟的宠物项目。
不幸的是,没有简单的方法可以做到这一点。因此,仅使用 touchstart
或 touchend
会给您带来其他问题,例如有人在单击按钮时开始滚动。我们使用 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();
});
tap
解决方案并逐个元素地分解 tap
事件?
tap
解决方案。我会更新我的答案。
tap
解决方案似乎与您的解决方案相同?
我搜索了一种没有 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);
}
}
在 jQuery 中,您可以绑定“touchend”事件,在点击后立即触发代码(就像键盘中的按键)。在当前的 Chrome 和 Firefox 平板电脑版本上测试。对于您的触摸屏笔记本电脑和台式设备,也不要忘记“点击”。
jQuery('.yourElements').bind('click touchend',function(event){ event.stopPropagation(); event.preventDefault(); // 其他一切 });
只是为了提供一些额外的信息。
在 iOS 10 上,我的页面上的 <button>
无法连续触发。总是有一个滞后。
我试过fastclick / Hammer / tapjs /用touchstart替换click,都失败了。
更新:原因似乎是按钮太靠近边缘!将它移到中心附近并滞后消失!
你应该明确声明被动模式:
window.addEventListener('touchstart', (e) => {
alert('fast touch');
}, { passive : true});
不定期副业成功案例分享