如何理解移动端的单击穿透

1.单击穿透原理

         1 其一是单击穿透情况:单击蒙层(mask)上面的 “ 关闭 ” 按钮,如果蒙层消失,一定是触发了 按钮下面元素的click事件,让蒙层消失。
         2.其二是页面单击穿透情况:如果按钮下面恰好是一个有 href 属性的a标签,也就是存在a标签,那么页面就会发生跳转。
         3.其三跨页面单击穿透情况:该情况不要会出现蒙层,直接单击页面内按钮跳转至新页,之后在新的页面中可以看到对应位置元素的click事件被触发了。

2.为什么会出现

            touchstart:在该DOM上(或者是冒泡到该DOM)上手指触摸开始即能立即触发。
            click:在该DOM上(或者冒泡到该DOM)上手指触摸开始,且手指没有在屏幕上移动,且这个DOM元素上手指离开屏幕,且触摸和离开屏幕之间的间隔较短才能触发。
            事件触发时间先后排序:touchstart => touchend => click。
            遮盖层:遮盖层的点击即使有小的延迟也没有影响,相反能给用户更好的体验,针对遮盖层采用自己的click事件,不会出现点击穿透的问题。

3.解决方案

          (1) 只用touch
                    该方法是一种较为简单的解决办法,能够完美地解决单击穿透问题,实行方案是把页面内所有的click事件都替换换成touch事件(touchstart、touched、tap)。
          (2) 只用click
                    这个方法在单击会带来300ms的延迟,所以页面内任何一个自定义使用click时都将增加300ms的延迟。
          (3) 轻触 (tap) 后延迟350ms再隐藏蒙层
                    这种方法相当于原先的操作改动最小,但缺点是隐藏蒙层变慢了,时间大约市350ms。
          (4) 只用touch
                    这种方法比较麻烦并且有缺陷,不推荐去使用。蒙层隐藏后,给按钮下面的元素添上pointer-events:none样式,让click穿过去,350ms后去掉这个样式。恢复响应的缺陷是蒙层消失后的350ms内,用户单机按钮下面的元素没反应,如果用户单机速度很快,会发现这个不足的地方。

4.代码实现

          4.1 最外层元素监听的触摸事件里,阻止默认行为。

btn.addEventListener("touchend",funtion(event){
	event.preventDefault();
})

          4.2 阻止所有元素的默认行为,document监听触摸事件。

document.addEventListener("touchstart",function(event){
	event.preventDefault();
},{passive:false})

           4.3 里面的元素使用没有点击特性的元素,比如用div代替a。

ass.forEach(function(item){
	item.addEventListener("touchend",function(){
		location.href = this.dataset.href;
	})
})

//  div中没有href属性,用的是data-href。在绑定监听时获取href
//  方式一:dataset.href要求属性data-href必须是data-
	// location.href = this.dataset.href;
//  方式二:利用getAttribute获取自定义属性的值
    // location.href = this.getAttribute("data-href")

           4.4 利用css的pointer-event,设置为none

btn.addEventListener("touchend",function(){
	// 先让a失去点击特性
	ass.forEach(function(item){
		item.style.pointerEvents = "none";
	})
});
cover.style.display = "none";

// 遮罩层消失之后且click动作发生之后,让a具有点击特性
setInterval(function(){
	ass.forEach(function(item){
		item.style.pointerEventys = "auto";
	});
},400)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值