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

文章目录

  • 移动端事件触发顺序
  • 300 毫秒延迟原因
  • 300 毫秒延迟产生的点击穿透问题
  • IOS的300毫秒延迟
    • 禁用缩放
    • 禁用双击缩放
    • 设置视口宽度
    • fastclick 库
    • 手动封装一个 tap 方法
  • fastclick 原理

移动端事件触发顺序

  • 在 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');
});

移动端事件顺序、解决300毫秒点击延迟_第1张图片

  • 点击关闭按钮,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('
                    
                    

你可能感兴趣的:(移动端与REM,移动端)