blog
blog copied to clipboard
移动端的300毫秒点击延迟和点击穿透问题
300毫秒延迟来历
在早期iphone设备中为了更好的适应设备网页的比例,加入双击缩放会将浏览器的网页缩放至原始比例。
当浏览器单击一次屏幕,浏览器需要去判断用户是想要打开链接还是会选择双击缩放,这就导致需要等待300毫秒来做进一步的判断。因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕.
在现今的移动web中,300毫秒的延迟影响了用户体验,大家都在想办法优化这个体验,300 毫秒点击延迟的来龙去脉阐述的更加清楚明白。
解决方法之Hammer.js
hammer.js是一款开源的移动端脚本框架,他可以完美的实现在移端开发的大多数事件,如:点击、滑动、拖动、多点触控等事件。不需要依赖任何其他的框架,并且整个框架非常小,在使用时非常简单,代码示例如下:
hammer中的tap事件
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Tap</title>
<script src="./js/hammer.js"></script>
<style type="text/css">
html,
body {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
.test {
width: 100%;
height: 50%;
background: #ffd800;
text-align: left;
}
.result {
width: 100%;
height: 50%;
background: #b6ff00;
text-align: left;
}
</style>
</head>
<body>
<div id="test" class="test">事件区域</div>
<div id="result" class="result">事件结果:点击触发
<br />
</div>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
//创建一个新的hammer对象并且在初始化时指定要处理的dom元素
var hammertime = new Hammer(document.getElementById("test"));
//添加事件
hammertime.on("tap", function (e) {
document.getElementById("result").innerHTML += "tap点击触发了,长按无效" + new Date().getTime() + "<br />";
//控制台输出
console.log(e);
});
document.querySelector("#test").onclick = function () {
document.getElementById("result").innerHTML += "原生点击触发了,长按无效" + new Date().getTime() + "<br />";
}
$("#test").click(function () {
$("#result")[0].innerHTML += "jq点击触发了,长按无效" + new Date().getTime() + "<br />";
})
</script>
</body>
</html>
})
设备测试
chrome和qq都不明显看不出来,safari...
chrome
自己写一个tap方法
在这里利用是否支持touch事件来做分别,支持的话使用touch事件,不支持则使用mouse事件,最后触发时间范围小于500毫秒的回调函数,也是可以使用的!
function tap(ele, touchFn) {
var SupportsTouches = ("createTouch" in document), //判断是否支持触摸
StartEvent = SupportsTouches ? "touchstart" : "mousedown", //支持触摸式使用相应的事件替代
EndEvent = SupportsTouches ? "touchend" : "mouseup";
var startTime = null,
endTime = null;
ele.addEventListener(StartEvent, function (e) {
startTime = e.timeStamp
console.log("startTime " + new Date().getTime())
})
ele.addEventListener(EndEvent, function (e) {
var context = this;
endTime = e.timeStamp
console.log("endTime " + new Date().getTime())
console.log('间距=' + (endTime - startTime))
if (endTime - startTime < 500) {
touchFn();
}
})
}
tap(document.querySelector("div"), function () {
console.log("complate " + new Date().getTime())
})
浏览器打印
Userful links
- https://thx.github.io/mobile/300ms-click-delay
- https://www.jianshu.com/p/16d3e4f9b2a9