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

wuchangjian2021-11-04 19:41:34编程学习

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)

相关文章

[react] 在React中怎么阻止事件的默认行为?

[react] 在React中怎么阻止事件的默认行为? event.pr...

elasticsearch做为日志中心的配置及优化

Hot-warm-cold architecture with Elasticsearc...

60集Python入门视频PPT整理 | Python编程基础及编程风格

学习视频来源:《马哥教育-Python入门教程》...

初识java和main语言

1,java的运行 先安装JDK,同时调整环境变量...

11. 盛最多水的容器 -- leetcode今日签到题

大家好,我是小鲨鱼,我来打卡今天的签到题了呀,...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。