300ms问题的由来
浏览器会等待300ms以确定用户是想单击还是双击。
最初是ios safari 为了解决手机端浏览pc网页时无法确定用户是单击还是双击缩放而设定了300ms等待这样一个约定,后来其他手机浏览器都复制了这个约定。但随着移动端web发展,对使用体验要求也越来越高,300ms的卡顿越来越难以接受。
目前的解决方案
归结起来是两个办法:
一、禁用双击缩放(meta 标签、touch-action都属于这类)
二、监听事件,不等300ms就触发,再移除300ms后的click事件(使用第三方库例如fastclick)
1.meta标签禁止缩放
<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1,maximum-scale=1">
2.浏览器会在视口宽度设置为设备宽度
<meta name="viewport" content="width=device-width">
时停用双击缩放行为,chrome 32开始支持,其他厂商也开始支持.
3.指针事件
touch-action属性规定了触摸输入能否触发UA的默认行为。
- auto:允许浏览器处理各类手势
- none:禁止浏览器处理各类手势
- manipulation: 允许平移,双指缩放,禁止双击缩放
支持情况:
4.fastclick 见下文
React-fastclick
give up, 存在点透问题
fastclick
FastClick is a simple, easy-to-use library for eliminating the 300ms delay between a physical tap and the firing of a click event on mobile browsers. The aim is to make your application feel less laggy and more responsive while avoiding any interference with your current logic.
原理:
移动端点击事件发生时,会触发touchStart => touchMove => touchEnd => click ,fastclick是在监听到touchEnd事件时,触发click事件,关键代码:
FastClick.prototype.onTouchEnd = function(event) {
...
this.sendClick(targetElement, event);
event.preventDefault();
...
};
FastClick.prototype.sendClick = function(targetElement, event) {
var clickEvent, touch;
...
// Synthesise a click event, with an extra attribute so it can be tracked
clickEvent = document.createEvent('MouseEvents');
clickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);
clickEvent.forwardedTouchEvent = true;
targetElement.dispatchEvent(clickEvent);
};
引入:
import fastclick from 'fastclick';
fastclick.attach(document.body);
缺点:
文件大小:26k => 10k左右
Reference
1.http://www.jianshu.com/p/459102cd0ee9
2.https://developer.mozilla.org/en-US/docs/Web/CSS/touch-action
网友评论