移动端 click 事件会有 300ms 的延时,原因是移动端屏幕双击会缩放(double tap to zoom) 页面。
解决方案:
1. 禁用缩放: 浏览器禁用默认的双击缩放行为并且去掉300ms 的点击延迟。
<meta name="viewport" content="user-scalable=no">
2.利用touch事件自己封装这个事件解决300ms 延迟。
原理就是:
当我们手指触摸屏幕,记录当前触摸时间
当我们手指离开屏幕, 用离开的时间减去触摸的时间
如果时间小于150ms,并且没有滑动过屏幕, 那么我们就定义为点击
代码如下:
//封装tap,解决click 300ms 延时
function tap (obj, callback) {
var isMove = false;
var startTime = 0; // 记录触摸时候的时间变量
obj.addEventListener('touchstart', function (e) {
startTime = Date.now(); // 记录触摸时间
});
obj.addEventListener('touchmove', function (e) {
isMove = true; // 看看是否有滑动,有滑动算拖拽,不算点击
});
obj.addEventListener('touchend', function (e) {
if (!isMove && (Date.now() - startTime) < 150) { // 如果手指触摸和离开时间小于150ms 算点击
callback && callback(); // 执行回调函数
}
isMove = false; // 取反 重置
startTime = 0;
});
}
//调用
tap(div, function(){ // 执行代码 });
3、使用插件:fastclick 插件解决300ms 延迟。
GitHub官网地址: https://github.com/ftlabs/fastclick
FastClick 是 FT Labs 专门为解决移动端浏览器 300 毫秒点击延迟问题所开发的一个轻量级的库。简而言之,FastClick 在检测到touchend事件的时候,会通过 DOM 自定义事件立即触发一个模拟click事件,并把浏览器在 300 毫秒之后真正触发的click事件阻止掉。使用方法如下。
第一步:在页面中引入fastclick.js文件。
第二步:在js文件中添加以下代码 在 window load 事件之后,在body上调用FastClick.attach()即可。
window.addEventListener(function(){
FastClick.attach( document.body );
},false );
如果你项目使用了JQuery,就将上面的代码改写成:
$(function() {
FastClick.attach(document.body);
});
4、使用 touchend 事件处理
不同于 click 和 touchstart,touchend 没有这个 300ms 的延迟,而是即时触发,你完全可以在 WebGL 或 canvase 游戏中进行实践,但是在web 页面中单单使用 touchend 并不一定靠谱.
1、如果用户在两个不同元素之间触发了 touchstart 和touchend,那么 click 不会被触发 .
2、如果用户触发了 touchstart,但是在touchend之前是一个长长的 touchmove 滚动, 那么 click 也不会被触发.
3、在站点上任然应该保留 click 事件以兼容那些非触摸设备,这是你就要考虑事件的重复触发问题.
在此处输入内容已有同行为我们封装了部分解决方法:
1、FastClick 来至于FT实验室的一个插件,仅仅只有10kb,但是能解决上面的2-4步.
2、Tappy 来自于Filament Group,仅仅1kb,概念上类似于上面的指针事件.问题:当你为多个元素进行这些事件绑定时,有可能出现性能的损耗.是否有完美的解决方案呢?
是否需要解决 300ms 在于自己的判断,300ms被设计出来是有特定的用途,上面的meta属性中进行了设定,在chrome和firefox下能起作用,希望其他厂商也能尽 快提供这类支持。touch-action: manipulation 这个css属性能把风险降到最低,虽然现在只有微软支持,但是作为W3C规范和HTML5test的一部分,因此也许我们并不需要等待太久。
原文链接:https://blog.csdn.net/qappleh/article/details/80419204