fastclick 解决移动端点击事件延迟300ms和点击穿透的问题

fastclick 解决移动端点击事件延迟300ms和点击穿透的问题,第1张

延迟 为什么移动端点击事件会有300ms延迟?

首款 iPhone开发时遇到一个问题:当时的网站都是为大屏幕设备所设计的,而小屏幕浏览桌面端站点的缩放时如何系统判断?于是做出一个双击缩放(double tap to zoom)的约定,这也是会有上述 300 毫秒延迟的主要原因。
双击缩放,顾名思义,即用手指在屏幕上快速点击两次,iOS 自带的 Safari 浏览器会将网页缩放至原始比例。 那么这和 300 毫秒延迟有什么联系呢?
假定这么一个场景: 用户在 iOS Safari 里边点击了一个链接。由于用户可以进行双击缩放或者双击滚动的 *** 作,当用户一次点击屏幕之后,浏览器并不能立刻判断用户是确实要打开这个链接,还是想要进行双击 *** 作。因此,iOS Safari 就等待 300 毫秒,以判断用户是否再次点击了屏幕。 鉴于iPhone的成功,其他移动浏览器都复制了 iPhone Safari 浏览器的多数约定,包括双击缩放,几乎现在所有的移动端浏览器都有这个功能。

解决办法

禁用缩放

<meta name = "viewport" content="user-scalable=no" > 

缺点: 网页无法缩放

更改默认视口宽度

<meta name="viewport" content="width=device-width">

css touch-action

touch-action:auto; //将其置为 none 即可移除目标元素的 300 毫秒延迟

tap事件
zepto的tap事件, 利用touchstart和touchend来模拟click事件

//封装tap解决click 300ms 延时
function tap (obj,callback) {
	var isMove = false;//记录手指是否移动
	var startTime = 0;//记录手指触摸的时间
	obj.addEventListener('touchstart',function(e){
		startTime = Date.now();//记录触摸时间
	})
	obj.addEventListener('touchmove',function(e){
		isMove = true;//查看手指是否滑动
	})
	obj.addEventListener('touchend',function(e){
		if(!isMove && (Date.now() - statrTime) < 150){
		callback && callback();
		}
		isMove = false;//取反 重置
		startTime = 0;
	})
};
tap(document.getElementById('dom'),()=>{
 	//执行代码 
})

fastclick
在检测到touchend事件的时候,会通过DOM自定义事件立即出发模拟一个click事件,并把浏览器在300ms之后真正的click事件阻止掉

<script type='application/javascript' src='./fastclick.js'></script>
if ('addEventListener' in document) {
	document.addEventListener('DOMContentLoaded', function() {
		FastClick.attach(document.body);
	}, false);
}
<script type='application/javascript' src='./jquery.js'></script>
<script type='application/javascript' src='./fastclick.js'></script>
	$(function() {
		FastClick.attach(document.body);
	});
var attachFastClick = require('fastclick');
attachFastClick(document.body);

缺点: 脚本相对较大

点透 为什么移动端点击事件会有点击穿透?

这是因为在移动端浏览器,事件执行的顺序是touchstart > touchend > click。而click事件有300ms的延迟,当touchstart事件把B元素隐藏之后,隔了300ms,浏览器触发了click事件,但是此时B元素不见了,所以该事件被派发到了A元素身上。

<style>
	.box{width: 500px;height: 500px;border: 1px solid #ccc;position: relative;}
	.click{width: 300px;height: 300px;background-color: blue;}
	.tap{width: 200px;height: 200px;background-color: red;position: absolute;left: 0;top:0;}
</style>
<body>
	<div class="box">
	    <div class="click"></div>
	    <div class="tap"></div>
	</div>
</body>
<script>
    var click = document.querySelector(".click");
    var tap = document.querySelector(".tap");
    tap.addEventListener("touchstart",function(){
        tap.style.visibility = "hidden";
        console.log(123);
    })
    click.addEventListener("click",function(){
        console.log(456);
    })
</script>

点击 tap 打印 123 456 ,tap标签隐藏

<script src="./fastclick.js"></script>
<script>
    FastClick.attach(document.body);
    var click = document.querySelector(".click");
    var tap = document.querySelector(".tap");
    tap.addEventListener("touchstart",function(){
        tap.style.visibility = "hidden";
        console.log(123);
    })
    click.addEventListener("click",function(){
        console.log(456);
    })
</script>

点击 tap 打印 123 ,tap标签隐藏
点击 click 打印 456

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/993710.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-21
下一篇 2022-05-21

发表评论

登录后才能评论

评论列表(0条)

保存