fastclick原理剖析及其用法

移动端点击延迟事件

    1. 移动端浏览器在派发点击事件的时候,通常会出现300ms左右的延迟。
    2. 原因: 移动端的双击会缩放导致click判断延迟。
      这是为了检查用户是否在做双击。为了能够立即响应用户的点击事件,才有了FastClick。

解决方式

    1. 禁用缩放 <meta name = "viewport" content="user-scalable=no" > 
      缺点: 网页无法缩放

    2. 更改默认视口宽度 <meta name="viewport" content="width=device-width"> 
      缺点: 需要浏览器的支持

    3. css touch-action touch-action的默为 auto,将其置为 none 即可移除目标元素的 300 毫秒延迟 缺点: 新属性,可能存在浏览器兼容问题

    4. tap事件 zepto的tap事件, 利用touchstart和touchend来模拟click事件
      缺点: 点击穿透

    5. fastclick 原理: 在检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后真正的click事件阻止掉
      缺点: 脚本相对较大

使用:

//JS    
// 引入   
<script type='application/javascript' src='/path/to/fastclick.js'></script>    
// 使用了jquery的时候    
$(function() {        FastClick.attach(document.body);    });    
// 没使用jquery的时候    
if ('addEventListener' in document) {        
document.addEventListener('DOMContentLoaded', 
function() {            
FastClick.attach(document.body);        
}, false);}    

 在vue中使用 :

//js    
// 安装    
npm install fastclick -S    
// 引入    
import FastClick from 'fastclick'    
// 使用    
FastClick.attach(document.body);

不需要使用fastclick的情况

以下这几种情况是不需要使用fastclick:

1、FastClick是不会对PC浏览器添加监听事件
2、Android版Chrome 32+浏览器,如果设置viewport meta的值为width=device-width,这种情况下浏览器会马上出发点击事件,不会延迟300毫秒。

<meta name="viewport" content="width=device-width, initial-scale=1">

3、所有版本的Android Chrome浏览器,如果设置viewport meta的值有user-scalable=no,浏览器也是会马上出发点击事件。
4、IE11+浏览器设置了css的属性touch-action: manipulation,它会在某些标签(a,button等)禁止双击事件,IE10的为-ms-touch-action: manipulation

 

问题BUG

引入fastclick.js ,ios点击输入框之后,点击软键盘上的 完成 时发现,轻击input就无法唤起软键盘,无法对输入框聚焦,必须长按或重压才行,ios11 后修复了移动点击300ms延迟

解决方法:在node_module里找到fastClick文件

FastClick.prototype.focus = function(targetElement) {
        var length;

        // Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.
        if (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month') {
            length = targetElement.value.length;
            targetElement.setSelectionRange(length, length);
            //修复bug ios11.3以上版本不弹出键盘,这里加上聚焦代码,让其强制聚焦弹出键盘
            targetElement.focus();
        } else {
            targetElement.focus();
        }
    };

 另外一种思路是 在 每一个input 强制加一个点击事件,点击后,聚焦 focus 即可。

参考:https://github.com/ftlabs/fastclick

 

posted @ 2019-01-04 18:32  想旅游咯  阅读(719)  评论(1编辑  收藏  举报