带你了解什么是点击穿透和如何解决点击穿透带来的问题

什么是点击穿透

用一个项目中可能会遇到的问题来说说,现在有页面login和页面home,登录按钮绑定的是touchstart事件,假设登录按钮的坐标是(200,500),在home页面的(200,500)处有一个元素a,元素a绑定了click事件,当我们点击登录按钮跳转到home页面时,我们会发现莫名其妙触发了这个click事件。这就是点击穿透。
可能有小伙伴说,为什么要使用touchstart事件,使用click事件不好吗,也就没有这样的问题了,那是因为在移动端touchstart相对于click是有一定优点的,touchstart 相对于 click 事件,click触发要慢个 50 ~ 300ms,它可以使得用户的操作更加流畅。虽然说可能会带来点击穿透的问题,但是这个问题还算很好解决的。

为什么会有点击穿透

touchstart触发后,会在300ms内触发一个click的默认行为。

点击穿透代码演示

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Documenttitle>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
       .box{
            background-color: aqua;
            width: 95vw;
            height:46vw;
            margin: auto;
            border: 1px solid black;
        }
       #mask{
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            line-height: 120px;
            background-color: rgba(0, 0, 0, .4);
            text-align: center;
            display: none;
        }
        style>
    head>
    
    <body>
        <div id="mask">轻触关闭遮罩层div>
        <div class="box">div>  
        <button id="btn">弹出遮罩层button>
    <script>
        const box=document.querySelector(".box")
        box.addEventListener("click",()=>{alert('box is clicked')})
        const mask=document.querySelector("#mask")
        document.querySelector("#btn").addEventListener("click",()=>{mask.style.display='block'})
        mask.addEventListener('touchstart',(e)=>{
        e.target.style.display='none'
        })
    script>
    body>
html>

h5端运行该网页,你会体验到什么是点击穿透

如何解决点击穿透

方案一:阻止默认事件的触发

mask.addEventListener('touchstart',(e)=>{
           e.preventDefault()                  // 阻止默认事件后,将不再触发触摸后的点击事件
           e.target.style.display='none'
        })

方案二:让消失元素的底部元素 在 300ms 左右暂时失去click监听功能

mask.addEventListener('touchstart',(e)=>{
            box.style.pointerEvents='none'     //让元素不监听鼠标事件
            setTimeout(()=>{
            box.style.pointerEvents='auto'
            },300)
            e.target.style.display='none'
        })

方案三:让要消失的元素延迟 300ms 左右消失

 mask.addEventListener('touchstart',(e)=>{
        setTimeout(()=>{
                e.target.style.display='none'
            },300)
 })

推荐使用方案一,后面两个方案只是为了增加你对点击穿透原理的了解。

你可能感兴趣的:(javascript,前端,html5)