我有一个菜单,要在焦点对准输入时显示,所以我使用了焦点和模糊事件来触发显示或隐藏菜单的功能。
问题是,当我想在菜单内添加事件(例如click事件)时,总是先触发输入的模糊事件,因此永远不会触发菜单的click事件
下面是示例代码来说明我的问题: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()函数)
预先感谢
答案 0 :(得分:2)
为此,您可以用CSS代替Java做很多事情。
在这里,为选择器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>
答案 1 :(得分:0)
这是一个不幸的副作用。 但是通过使用不同的事件可以很容易地解决它。
您可以仅对所有这3个事件使用click事件,而不必使用focus / blur处理程序,因为对输入进行聚焦与在其内部单击相同。而且,模糊输入与单击输入外部相同。
因此,如果我们在输入框中显示onclick框,则可以向文档的其余部分添加另一个click事件。在该点击事件中,我们可以检查当前点击是否在该框内,并采取相应措施。
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解决方案是一种更好,更轻松的解决方案。
答案 2 :(得分:0)
您可以使用两件事:
event.relatedTarget-仅对focus
有效,并且blur
中的relatedTarget
事件仅在tabindex=1
具有event.relatedTarget
或更大时包含一个值。
useCapture
phase of addEventListener
,可让您在大多数事情到达事件之前就进行事件。
在下面的示例中,我同时使用了两者,尽管我实际上只需要使用#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);
,并防止关闭框。 / p>
#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>
{{1}}
答案 3 :(得分:-1)
我认为最快,最简单的方法是在setTimeout
函数中使用hide
。
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>