300ms延时问题
移动设备上的浏览器默认会在用户点击屏幕大约延迟300毫秒后才会触发点击事件,这是为了检查用户是否在做双击。
那么如何解决这个问题呢?我使用的是fastclick.js
参考:https://github.com/ftlabs/fastclick
FastClick的使用
安装fastclick
安装fastclick可以使用npm,Component和Bower。另外也提供了Ruby版的gem fastclick-rails以及.NET提供了NuGet package。最直接的可以在页面引入fastclick js文件。如:
在页面直接引入fastclick.js
<script type='application/javascript' src='/path/to/fastclick.js'></script>
使用npm安装
npm install fastclick
初始化FastClick实例
初始化FastClick实例建议在页面的DOM文档加载完成后。
纯Javascript版
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
jQuery版
$(function() {
FastClick.attach(document.body);
});
类似Common JS的模块系统方式
var attachFastClick = require('fastclick');
attachFastClick(document.body);
调用require('fastclick')会返回FastClick.attach函数。
使用needsclick过滤特定的元素
如果页面上有一些特定的元素不需要使用fastclick来立刻触发点击事件,可以在元素的class上添加needsclick:
<a class="needsclick">Ignored by FastClick</a>
实例如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style type="text/css">
* {
margin: 0;
padding: 0;
}
p {
width: 100%;
font-size: 0.7em;
}
.stats {
margin-top: 1em;
}
input {
width: 10em;
}
div {
width: 100%;
}
.test {
margin: 1em auto;
width: 3em;
line-height: 3em;
border: 1px solid black;
font-size: 2em;
text-align: center;
}
</style>
</head>
<body>
<p>A层对点击事件的响应正常,在iOS上会导致300毫秒的延迟。</p>
<p>B层通过FastClick增强,并将毫不延迟地启动click处理程序。</p>
<p>这些层将在不支持触摸事件的平台上正常工作。</p>
<p class="stats">Touch end time: <input id="te-time" value="0" /></p>
<p class="stats">Click event time: <input id="c-time" /></p>
<p class="stats">Difference: <input id="d-time" /></p>
<div>
<div class="test" id="test-a">A</div>
<div class="test" id="test-b">B</div>
</div>
<script src="https://cdn.bootcss.com/fastclick/1.0.6/fastclick.min.js"></script>
<script type="application/javascript">
window.addEventListener(
'load',
function () {
var testA, testB, teTime, cTime
testA = document.getElementById('test-a')
testB = document.getElementById('test-b')
// Android 2.2 needs FastClick to be instantiated before the other listeners so that the stopImmediatePropagation hack can work.
FastClick.attach(testB)
testA.addEventListener(
'touchend',
function (event) {
teTime = Date.now()
document.getElementById('te-time').value = teTime
},
false
)
testA.addEventListener(
'click',
function (event) {
cTime = Date.now()
document.getElementById('c-time').value = cTime
document.getElementById('d-time').value = cTime - teTime
testA.style.backgroundColor = testA.style.backgroundColor ? '' : 'YellowGreen'
},
false
)
testB.addEventListener(
'touchend',
function (event) {
teTime = Date.now()
document.getElementById('te-time').value = teTime
document.getElementById('d-time').value = cTime - teTime
},
false
)
testB.addEventListener(
'click',
function (event) {
cTime = Date.now()
document.getElementById('c-time').value = cTime
testB.style.backgroundColor = testB.style.backgroundColor ? '' : 'YellowGreen'
},
false
)
},
false
)
</script>
</body>
</html>
使用ipone6/7/8测试结果如下
先点击A
再点击B
不需要使用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