input框失焦bug问题解决

问题引入

假设有这样一个功能需求,input框聚焦时,框下方列表会显示,而失焦时列表会隐藏,列表点击时应拿到对应列表项内容,然后进行对于输入框的渲染或其他操作。代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        ul{
            display: none;
        }
    </style>
</head>
<body>
    <input type="text" id="ipt">
    <ul id="ul">
        <li>111</li>
        <li>222</li>
        <li>333</li>
    </ul>
</body>
<script>
    ipt.onfocus=()=>{
        ul.style.display='block'
    }
    ipt.onblur=()=>{
        ul.style.display='none'
    }
    ul.onclick=(e)=>{
        ipt.value=e.target.innerText
    }
</script>
</html>

上述代码会产生这样一个bug:当ul的点击事件触发时,会先触发失焦事件,让ul隐藏,然后再触发点击事件,而此时点击拿不到ul中的li数据,这就好比在某人坐下瞬间抽掉板凳一样

问题解决

面对上述问题,有以下三种解决方式:

法1:将点击触发改为按下时触发

如果改成按下时就触发,那么事件发生过程为触发按下事件然后才触发失焦事件,代码改为:

    //不变
    ipt.onblur=()=>{
        setTimeOut(()=>{
            ul.style.display='none'
        },100)
    }

    ul.onmousedown=(e)=>{
        ipt.value=e.target.innerText
    }

法2:将失焦事件延迟触发

如果将失焦事件添加延迟效果,那么事件触发过程就是在失焦延迟的过程中触发点击事件,延迟结束后点击事件已经运行完成,再触发失焦效果。代码修改如下:

    ipt.onblur=()=>{
        setTimeOut(()=>{
            ul.style.display='none'
        },100)
    }
    //不变
    ul.onclick=(e)=>{
        ipt.value=e.target.innerText
    }

法3:监听document的冒泡事件

这种方法是利用事件冒泡,判断点击事件的触发源,控制ul的显示或隐藏的同时获得对应li的值

    let html=document.querySelector('html')
    html.onclick=(e)=>{
        if(e.target.nodeName!=='INPUT'){
            console.log(e.target.nodeName)
            ul.style.display='none';
        }
    }
    //不变
    ul.onclick=(e)=>{
        ipt.value=e.target.innerText
    }
    //不需要设置失焦事件

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值