我有一个输入框,当 focus 事件触发时,提示文本列表将显示在输入框下方,当 blur 事件触发时,列表将被隐藏。
我在提示列表中添加了点击事件监听器,但是当我尝试点击提示时,输入框上的模糊事件首先被触发,所以提示上的点击事件永远不会被触发。
有没有办法让提示文本上的点击事件先触发?之后,我将触发模糊事件处理程序以隐藏提示文本。
var textEl = document.getElementById("text"),
listEl = document.getElementById("list");
textEl.onfocus = function() {
listEl.style.display = "initial";
}
textEl.onblur = function() {
listEl.style.display = "none";
}
listEl.onclick = function(event) {
var item = event.target;
alert(item.textContent);
textEl.value = item.textContent;
}
#container {
position: relative;
width: 300px;
margin: auto;
}
input {
width: 100%;
}
#list {
display: none;
position: absolute;
width: 100%;
background: #fff;
}
.item {
padding: 12px 0;
border-bottom: 1px solid #ccacac;
}
<div id="container">
<input type="text" id="text">
<div id="list">
<div class="item"> item 1</div>
<div class="item"> item 2</div>
<div class="item"> item 3</div>
</div>
</div>
最佳答案
您可以在 listEl
上使用 mouseenter
和 mouseleave
来决定 textEl
是否应该响应blur
事件。因此,基于此,您可以附加/分离模糊处理程序。
var textEl = document.getElementById("text"),
listEl = document.getElementById("list");
textEl.onfocus = function() {
listEl.style.display = "initial";
}
var blurHandler = function() {
listEl.style.display = "none";
};
textEl.onblur = blurHandler;
listEl.onclick = function(event) {
var item = event.target;
alert(item.textContent);
textEl.value = item.textContent;
}
listEl.onmouseenter = function(event) {
textEl.onblur = null;
}
listEl.onmouseleave = function(event) {
textEl.onblur = blurHandler;
// Also trigger the blur handler, if the element is not in focus.
if(document.activeElement.id !== "text"){
blurHandler();
}
}
#container {
position: relative;
width: 300px;
margin: auto;
}
input {
width: 100%;
}
#list {
display: none;
position: absolute;
width: 100%;
background: #fff;
}
.item {
padding: 12px 0;
border-bottom: 1px solid #ccacac;
}
.item:hover {
padding: 12px 0;
border-bottom: 1px solid #ccacac;
color: red;
}
<div id="container">
<input type="text" id="text">
<div id="list">
<div class="item"> item 1</div>
<div class="item"> item 2</div>
<div class="item"> item 3</div>
</div>
</div>
或者,您可以为其使用一些 CSS。例如,当 input
悬停或处于焦点时,您可以在列表上设置 display: block
;或者 list
本身处于焦点或悬停在上面。
#text:focus ~ #list, #list:focus,
#text:hover ~ #list, #list:hover{
display: block;
}
由于它摆脱了那些 JS 事件处理程序,我认为它在两者中更可取。
var textEl = document.getElementById("text"),
listEl = document.getElementById("list");
listEl.onclick = function(event) {
var item = event.target;
alert(item.textContent);
textEl.value = item.textContent;
}
#container {
position: relative;
width: 300px;
margin: auto;
}
#list {
display: none;
position: absolute;
width: 100%;
background: #fff;
}
#text:focus ~ #list, #list:focus,
#text:hover ~ #list, #list:hover{
display: block;
}
input {
width: 100%;
}
.item {
padding: 12px 0;
border-bottom: 1px solid #ccacac;
}
.item:hover {
padding: 12px 0;
border-bottom: 1px solid #ccacac;
color: red;
}
<div id="container">
<input type="text" id="text">
<div id="list">
<div class="item"> item 1</div>
<div class="item"> item 2</div>
<div class="item"> item 3</div>
</div>
</div>
关于javascript - 如何在隐藏元素之前触发元素的事件监听器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46370017/