如何防止模糊事件表单取消点击事件



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

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

下面是一个示例代码来说明我的问题:https://jsfiddle.net/f7xvg1L9/27/

function hide () {
document.getElementById('box').style.display = 'none';
}
function show () {
document.getElementById('box').style.display = 'block';
}
function select () {
document.getElementById('select').innerHTML = 'selected';
}
document.getElementById('input').addEventListener('blur', hide)
document.getElementById('input').addEventListener('focus', show)
document.getElementById('box').addEventListener('click', select)
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
<input type='text' id='input'/>
<div id='box'>Test</div>
<p id='select'></p>

(select((函数从未被调用(

提前感谢

您可以用CSS而不是Javascript做很多事情。

这里,为选择器input:focus + #box, #box:active设置一个CSS规则,它显示box

#box:active在盒子消失之前注册点击,没有它就无法工作。

document.getElementById('box').addEventListener('click',() => {
document.getElementById('select').innerHTML = 'selected';
});
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
input:focus + #box, #box:active{
display: block;
}
<input type='text' id='input'/>
<div id='box'>
Test
</div>
<p id='select'></p>

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

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

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

var box = document.getElementById('box');
var input = document.getElementById('input');
var change_text = function() {
box.innerHTML = 'selected';
};
var outside_click = function( event ) {
if ( !box.contains(event.target) ) {
box.style.display = 'none';
document.removeEventListener('click', outside_click);
}
};
var show_box = function( event ) {
event.stopPropagation();
box.style.display = 'block';
document.addEventListener('click', outside_click);
};
box.addEventListener('click', change_text);
input.addEventListener('click', show_box);
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
<input type='text' id='input'/>
<div id='box'>Test</div>

编辑:但是上面发布的CSS解决方案是一个更好更容易的解决方案。

你可以使用两种东西:

  • event.relatedTarget-这仅对上的focusblur事件有效。仅当relatedTarget具有tabindex=1或更大值时才包含一个值。

  • addEventListeneruseCapture阶段,它允许您在大多数事情发生之前了解事件。

在下面的例子中,我同时使用了它们,尽管我实际上只需要使用event.relatedTarget,因为这让我看到用户正在单击#box,并阻止关闭框。

function hide (evt) {
if (evt.relatedTarget && evt.relatedTarget.id === 'box') {
document.getElementById('box').style.display = 'none';
document.getElementById('input').focus();
}
else {
document.getElementById('box').style.display = 'none';
}
}
function show (evt) {
document.getElementById('box').style.display = 'block';
}
function select (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);
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
<input type="text" id="input"/>
<div id="box" tabindex="1">
Test
</div>
<p id="select"></p>

我认为最快速、最简单的方法是在hide函数中使用setTimeout

function hide () {
setTimeout(function(){
document.getElementById('box').style.display = 'none';
}, 300)
}
function show () {
document.getElementById('box').style.display = 'block';
}
function select () {
document.getElementById('select').innerHTML = 'selected';
}
document.getElementById('input').addEventListener('blur', hide)
document.getElementById('input').addEventListener('focus', show)
document.getElementById('box').addEventListener('click', select)
#box {
width: 100px;
height: 50px;
background-color: red;
display: none;
}
<input type='text' id='input'/>
<div id='box'>Test</div>
<p id='select'></p>

最新更新