<meta name="viewport" content="user-scalable=no,initial-scale=1,maximun-scale=1"/>
touch-action: none
仅IE支持
touchstart
和 touchend
事件,记录两者触发时间,如果小于 150ms 且在此过程中没有滑动过屏幕,就当做 click 事件,然后执行回调<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<button class="btn">点我</button>
<script>
/**
* 封装tap 解决移动端click事件300ms延时问题
* @param ele 监听元素
* @param cb 执行的回调函数
*/
function tap(ele, cb) {
let startTime = 0, // 触摸开始时间
isMove = false; // 是否有滑动
ele.addEventListener('touchstart', () => {
// 记录开始触摸时间
startTime = Date.now();
});
ele.addEventListener('touchmove', () => {
// 有滑动 算拖拽 不算点击
isMove = true;
});
ele.addEventListener('touchend', () => {
// 从 touchstart 到 touchend 时间不超过 150ms 且没有滑动屏幕
// 就算 click 事件
if (Date.now() - startTime < 150 && !isMove) {
cb && cb();
}
// 重置变量
startTime = 0;
isMove = false;
})
}
// 调用
tap(document.getElementsByClassName('btn')[0], () => {
console.log('click');
})
</script>
</body>
</html>
// 消除所有元素click延时
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
// 当使用click事件时 不会再有300ms延时
div.addEventListener('click',function () {
// 业务处理
})
不能,使用 touchstart
去代替 click
事件有两个不好的地方
touchstart
是手指触摸屏幕就触发,有时候用户只是想滑动屏幕, 却触发了 touchstart
事件,这不是我们想要的结果touchstart
事件在某些场景下可能会出现点击穿透的现象
touchstart
事件上注册了一个回调函数,该回调函数的作用是隐藏B元素。我们发现,当我们点击B元素,B元素被隐藏了,随后,A元素触发了 click
事件。touchstart > touchend > click
。而 click
事件有 300ms 的延迟,当 touchstart
事件把B元素隐藏之后,隔了300ms,浏览器触发了 click
事件,但是此时B元素不见了,所以该事件被派发到了A元素身上。如果A元素是一个链接,那此时页面就会意外地跳转。<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no" />
<title></title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.item {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 200px;
background: pink;
opacity: .5;
}
</style>
</head>
<body>
<div class="item"></div>
<a href="<http://www.bilibili.com>">B站</a>
</body>
<script type="text/javascript">
window.onload = function () {
/*
1.pc端的事件可以在移动端触发
2.PC端事件有300毫秒延迟
3.移动端事件不会有延迟
当点击item和a标签重叠的部分时
首先触发了移动端没有延迟的touchstart事件,
调用了该事件的回调函数,隐藏了item
接着300ms延迟以后原地触发了pc端click事件,
此时由于item已经消失,所以“点”在了a标签上,
导致跳转页面
*/
var item = document.querySelector(".item");
var a = document.querySelector("a");
item.addEventListener("touchstart", function () {
console.log("touchstart");
this.style.display = "none";
})
a.addEventListener("click",function(){
console.log("click");
})
}
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1.0,user-scalable=no" />
<title></title>
<style type="text/css">
* {
margin: 0;
padding: 0;
}
.item {
position: absolute;
left: 0;
top: 0;
width: 200px;
height: 200px;
background: pink;
opacity: .5;
}
</style>
</head>
<body>
<div class="item"></div>
<a href="<http://www.atguigu.com>">回娘家</a>
<a href="<http://www.atguigu.com>">回娘家</a>
<a href="<http://www.atguigu.com>">回娘家</a>
<a href="<http://www.atguigu.com>">回娘家</a>
<a href="<http://www.atguigu.com>">回娘家</a>
<a href="<http://www.atguigu.com>">回娘家</a>
<a href="<http://www.atguigu.com>">回娘家</a>
</body>
<script src="<https://cdn.bootcss.com/fastclick/1.0.6/fastclick.min.js>"></script>
<script type="text/javascript">
// 引入 fastclick.js
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
window.onload = function () {
var item = document.querySelector(".item");
var a = document.querySelector("a");
item.addEventListener("touchstart", function () {
console.log("touchstart");
this.style.display = "none";
})
a.addEventListener("click", function () {
console.log("click");
})
}
</script>
</html>
*Note: As of late 2015 most mobile browsers - notably Chrome and Safari - no longer have a 300ms touch delay, so fastclick offers no benefit on newer browsers, and risks introducing bugs into your application. Consider carefully whether you really need to use it.
注意:自 2015 年末以来,大多数移动浏览器 - 特别是 Chrome和 Safari - 不再有300毫秒的触摸延迟,因此在更新的浏览器上使用 fastclick不会带来任何好处,并可能在应用程序中引入错误。请仔细考虑是否真的需要使用它。
—* https://github.com/ftlabs/fastclick
阅读更多: