移动端事件顺序、解决300毫秒点击延迟

移动端事件触发顺序

  • 在 touchstart ,touchmove 或者 touchend 事件中的任意一个调用 event.preventDefault(),
  • 在触摸的过程中触发了 touchcancel 事件,后面的鼠标事件将不会被触发
touchstart
touchmove
touchend
mousemove
mousedown
mouseup
click

300 毫秒延迟原因

  • 移动浏览器在 touchend 和 click 之间应用了300-350ms的延迟,以等待是否会出现双击缩放文本的手势

300 毫秒延迟产生的点击穿透问题

<div class="container">
    <div id="underLayer">底层元素</div>

    <div id="popupLayer">
        <div class="layer-title">弹出层</div>
        <div class="layer-action">
            <button class="btn" id="closePopup">关闭</button>
        </div>
    </div>
</div>
<div id="bgMask"></div>
$('#closePopup').on('tap', function(e){
    $('#popupLayer').hide();
    $('#bgMask').hide();
});

$('#underLayer').on('click', function(){
    alert('underLayer clicked');
});

在这里插入图片描述

  • 点击关闭按钮,touchend 首先触发 tap,弹出层和遮罩就被隐藏了。touchend 后继续等待 300ms 发现没有其他行为了,则继续触发 click,而由于click事件的滞后性(300ms),在这 300ms 内上层元素隐藏或消失了,导致下层同样位置的 DOM 元素触发了click事件(如果是input框则会触发focus事件),看起来就像点击的target“穿透”到下层去了。

IOS的300毫秒延迟

  • iOS 8 之前一直都是 UIWebView,iOS 8 出了个 WKWebView,UIWebView 300ms 延迟的问题到现在一直存在,哪怕是最新的 iOS 版本。
  • WKWebView 在 iOS 9.3 的时候将这个问题给修复了。

禁用缩放

  • Chrome on Android (all versions)、iOS 9.3
  • Chrome 32 对移动端进行了优化,可以不禁用缩放,也能解决延迟的问题
<meta name="viewport" content="user-scalable=no" />

禁用双击缩放

html {
  touch-action: manipulation; // IE11+,只允许滚动和持续缩放,其他默认支持的行为都会被禁用;例如双击缩放
  -ms-touch-action: manipulation; // IE10
}

设置视口宽度

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

fastclick 库

<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1,minimum-scale=1, user-scalable=no" />

<script
	src="https://as.alipayobjects.com/g/component/fastclick/1.0.6/fastclick.js">
</script>

<script>
	if ('addEventListener' in document) {
		document.addEventListener('DOMContentLoaded', function() {
		FastClick.attach(document.body);
		}, false);
	}
	if(!window.Promise) {
	  document.writeln('<script src="https://as.alipayobjects.com/g/component/es6-promise/3.2.2/es6-promise.min.js" '+'>'+'<'+'/'+'script>');
	}
</script>

手动封装一个 tap 方法

//封装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(div,function(){ //执行代码 });

fastclick 原理

  • 在 touchend 阶段 调用 event.preventDefault,然后通过 document.createEvent 创建一个 MouseEvents,然后 通过 event​Target​.dispatch​Event 触发对应目标元素上绑定的 click 事件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值