Javascript 如何防止模糊事件表单覆盖单击事件?

Javascript 如何防止模糊事件表单覆盖单击事件?,javascript,html,Javascript,Html,我有一个菜单,我想在输入被聚焦时显示它,所以我使用输入的焦点和模糊事件来触发显示或隐藏菜单的功能 问题是,当我想在菜单中添加事件(例如单击事件)时,总是首先触发输入的模糊事件,因此永远不会触发菜单的单击事件 下面是一个示例代码来说明我的问题: 函数隐藏(){ document.getElementById('box').style.display='none'; } 函数显示(){ document.getElementById('box').style.display='block'; }

我有一个菜单,我想在输入被聚焦时显示它,所以我使用输入的焦点和模糊事件来触发显示或隐藏菜单的功能

问题是,当我想在菜单中添加事件(例如单击事件)时,总是首先触发输入的模糊事件,因此永远不会触发菜单的单击事件

下面是一个示例代码来说明我的问题:

函数隐藏(){
document.getElementById('box').style.display='none';
}
函数显示(){
document.getElementById('box').style.display='block';
}
函数选择(){
document.getElementById('select')。innerHTML='selected';
}
document.getElementById('input').addEventListener('blur',hide)
document.getElementById('input')。addEventListener('focus',show)
document.getElementById('box')。addEventListener('click',select)
#框{
宽度:100px;
高度:50px;
背景色:红色;
显示:无;
}

试验

为此,您可以用CSS而不是Javascript做很多事情

在这里,为选择器
input:focus+#box、#box:active
设置CSS规则,该选择器显示

#box:active
用于在框消失之前注册对框的单击,没有它就无法工作

document.getElementById('box').addEventListener('click',()=>{
document.getElementById('select')。innerHTML='selected';
});
#框{
宽度:100px;
高度:50px;
背景色:红色;
显示:无;
}
输入:焦点+#框,#框:活动{
显示:块;
}

试验

我认为最快捷、最简单的方法是在
隐藏
功能中使用
setTimeout

函数隐藏(){
setTimeout(函数(){
document.getElementById('box').style.display='none';
}, 300)
}
函数显示(){
document.getElementById('box').style.display='block';
}
函数选择(){
document.getElementById('select')。innerHTML='selected';
}
document.getElementById('input').addEventListener('blur',hide)
document.getElementById('input')。addEventListener('focus',show)
document.getElementById('box')。addEventListener('click',select)
#框{
宽度:100px;
高度:50px;
背景色:红色;
显示:无;
}

试验

这是一个不幸的副作用。 但是,通过使用不同的事件可以很容易地解决这个问题

不使用焦点/模糊处理程序,您只需对所有3个事件使用单击事件,因为聚焦输入与在输入中单击相同。模糊输入与在输入外部单击相同

因此,如果我们在单击输入时显示该框,那么我们可以向文档的其余部分添加一个不同的单击事件。在点击事件中,我们可以检查当前点击是否在框内,并相应地采取行动

var-box=document.getElementById('box');
var input=document.getElementById('input');
var change_text=函数(){
box.innerHTML='selected';
};
变量外部点击=功能(事件){
如果(!box.contains(event.target)){
box.style.display='none';
文档。删除EventListener('单击',外部单击);
}
};
变量显示框=函数(事件){
event.stopPropagation();
box.style.display='block';
document.addEventListener(“单击”,外部单击);
};
box.addEventListener(“单击”,更改文本);
input.addEventListener('单击',显示\u框)
#框{
宽度:100px;
高度:50px;
背景色:红色;
显示:无;
}


测试您可以使用的两件事:

  • -这仅适用于上的
    聚焦
    模糊
    事件,仅当
    相关目标
    具有
    tabindex=1
    或更大时才包含值

  • 它允许你在大多数事情发生之前就开始关注事件

在下面的示例中,我使用了这两种方法,尽管我实际上只需要使用
事件.relatedTarget
,因为这让我看到用户正在单击
#框
,并阻止关闭该框

函数隐藏(evt){
if(evt.relatedTarget&&evt.relatedTarget.id==='box'){
document.getElementById('box').style.display='none';
document.getElementById('input').focus();
}
否则{
document.getElementById('box').style.display='none';
}
}
功能显示(evt){
document.getElementById('box').style.display='block';
}
功能选择(evt){
document.getElementById('select')。innerHTML='selected';
}
document.getElementById('input').addEventListener('blur',hide);
document.getElementById('input')。addEventListener('focus',show);
document.getElementById('box').addEventListener('click',select,true)
#框{
宽度:100px;
高度:50px;
背景色:红色;
显示:无;
}

试验

这将导致一场以竞赛条件进行的军备竞赛