移动端CSS事件穿透解决方案

发表时间: 2024-05-02 22:08

移动端的点透:当上层元素发生点击的时候, 下层元素也有点击(焦点)特性, 在300ms之后, 如果上层元素消失或者隐藏,

目标点就会"漂移"到下层元素身上, 就会触发点击行为。

<a href="http://baidu.com">百度一下</a><p>pc点击事件</p><div></div>
<script type="text/javascript">    //pc端事件是可以在移动端使用的 但是存在一些问题(事件点透)-pc端事件比移动端事件慢300ms    var oDiv = document.getElementsByTagName("div")[0];    var oP = document.getElementsByTagName("p")[0];    oP.onclick = function(){ //pc端事件    this.style.color = "orange";    }    oDiv.addEventListener("touchend",function(){ //移动端事件    this.style.display = "none";    },true);</script>

如果我们在百度一下PC点击事件上方进行点击会发现当红色区域隐藏后还会触发其自身的事件。这种现象就是事件点透。

成因

我们上面说过, 移动设备能够响应click事件, 不过比较慢, 这是为什么?

因为click事件触发之后, 要等200ms到300ms左右, 因为浏览器有一些默认的手指快捷操作, 比如:快速双击两次屏幕视口会放大, 弹出辅助菜单等等。

大家用手机上网的时候, 尤其看一些PC端网站, 双击屏幕, 当前视口就变大了。

本质上:PC端事件比移动端的事件略慢, 大概是在300ms左右。所以我们也称这种现象为300毫秒延迟。

实例: 事件点透

<!DOCTYPE html><html><head><meta charset="UTF-8"><title></title><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /><style type="text/css">*{    margin: 0;    padding: 0;    list-style: none;    font-size: 5vw;}div{    width: 100vw;    height: 50vh;    text-align: center;    background-color: rgba(255,0,0,0.5);    position: absolute;    left: 0;    top: 0;}</style></head><body><div></div><a href="http://xxxxxx.com">JavaScript</a><mark></mark><span>我没有点击行为</span><script type="text/javascript">    var div = document.getElementsByTagName("div")[0];    div.addEventListener("touchstart",function(){    this.style.display = "none";    //this.style.backgroundColor = "rgba(0,255,0,0.5)";    },false)    var mark = document.getElementsByTagName("mark")[0];    mark.onclick = function(){    this.style.color = "red"; //字体变成红色    }//事件点透:当上层元素(div)有点击行为时,当上层元素消失,这种点击行为会飘到下层(mark)(点击事件、具有点击行为)元素身上//还需要注意上层元素是移动端事件 下层元素如果执行事件必须是PC端事件//原因:300ms延迟</script></body></html>

解决方法: 在移动端中全部使用移动端事件代替PC端事件 ontouchstart

<!DOCTYPE html><html><head><meta charset="UTF-8"><title></title><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /><style type="text/css">*{    margin: 0;    padding: 0;    list-style: none;    font-size: 5vw;}div{    width: 100vw;    height: 50vh;    text-align: center;    background-color: rgba(255,0,0,0.5);    position: absolute;    left: 0;    top: 0;}</style></head><body><div></div><a href="http://xxxxxx.com">JavaScript</a><mark>JavaScript</mark><script type="text/javascript">    var div = document.getElementsByTagName("div")[0];    div.addEventListener("touchstart",function(){    this.style.display = "none";    //this.style.backgroundColor = "rgba(0,255,0,0.5)";    },false)    var mark = document.getElementsByTagName("mark")[0];    //在移动端中全部使用移动端事件代替PC端事件    mark.ontouchstart = function(){    this.style.color = "red";    }    //事件点透:当上层元素有点击行为时,当上层元素消失,这种点击行为会飘到下层(点击事件、具有点击行为)元素身上    //还需要注意上层元素是移动端事件 下层元素如果执行事件必须是PC端事件    //原因:300ms延迟</script></body></html>

超链接如何解决点透

<!DOCTYPE html><html><head><meta charset="UTF-8"><title></title><meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" /><style type="text/css">*{    margin: 0;    padding: 0;    list-style: none;    font-size: 5vw;}div{    width: 100vw;    height: 50vh;    text-align: center;    background-color: rgba(255,0,0,0.5);    position: absolute;    left: 0;    top: 0;}</style></head><body><div></div><!--<a href="http://xxxxxx.com">JavaScript</a>--><!--<p data-url="http://xxxxxx.com">我来替换那些具有点击行为的元素比如a</p><p data-url="http://qq.com">我来替换那些具有点击行为的元素比如a</p><p data-url="http://baidu.com">我来替换那些具有点击行为的元素比如a</p><a data-href="http://baidu.com">百度</a><a data-href="http://163.com">网易</a><a data-href="http://qq.com">腾讯</a><a data-href="http://taobao.com">淘宝</a><p>我就是凑热闹的</p><script type="text/javascript">    var div = document.getElementsByTagName("div")[0];    div.addEventListener("touchstart",function(){        this.style.display = "none";        //this.style.backgroundColor = "rgba(0,255,0,0.5)";    },false)    //var ps = document.getElementsByTagName("p");    var ps = document.querySelectorAll("p[data-url]");        for(var i=0;i<ps.length;i++){            ps[i].ontouchstart = function(){            window.location.href = this.getAttribute("data-url");        }    }</script></body></html>