javascript - 两个事件同时触发时如何控制执行顺序
问题描述
这是一个简单的下拉菜单,包含input
HTML 和纯 JavaScript(无 JQuery)。我不想使用带有选项标签的预定义 HTML 列表,因为我需要滚动条、样式等。
我隐藏了列表onblur
,但是在单击项目列表之前触发了此事件。所以结果是我无法单击下拉菜单的项目,因为列表事先被隐藏了。
这是代码:
function showList(){
elem = document.getElementById("list");
elem.className = "unhidden";
}
function hideList(){
elem = document.getElementById("list");
elem.className = "hidden";
}
function showSuccess(){
elem = document.getElementById("successDiv");
elem.innerHTML = "code successful!";
}
.hidden { display: none; }
.unhidden { display: block; }
<html>
<head>
</head>
<body>
<input onfocus="showList();" onblur="hideList();"/>
<div id="list" class="hidden">
<a href="#" onclick="showSuccess();">click for success</a>
</div>
<div id="successDiv">
</div>
</body>
</html>
解决方案
最简单的解决方案是在隐藏元素之前使用setTimeout添加一个小的延迟。在下面的示例中,我在删除类之前等待了 250 毫秒。
function showList(){
elem = document.getElementById("list");
elem.className = "unhidden";
}
function hideList(){
setTimeout(function() {
elem = document.getElementById("list");
elem.className = "hidden";
}, 250); // Wait 250 milliseconds
}
function showSuccess(){
elem = document.getElementById("successDiv");
elem.innerHTML = "code successful!";
}
.hidden { display: none; }
.unhidden { display: block; }
<html>
<head>
</head>
<body>
<input onfocus="showList();" onblur="hideList();"/>
<div id="list" class="hidden">
<a href="#" onclick="showSuccess();">click for success</a>
</div>
<div id="successDiv">
</div>
</body>
</html>
编辑:更强大的解决方案
您可以查看相关事件,如果它在列表中,请在单击它之前不要关闭它。
const input = document.querySelector("#input");
const list = document.querySelector("#list");
const listItems = document.querySelectorAll("#list a");
const success = document.querySelector("#successDiv");
input.addEventListener("focus", showList);
input.addEventListener("blur", hideList);
for(const listItem of listItems) {
listItem.addEventListener("click", showSuccess);
}
function showList() {
list.classList.remove("hidden");
}
function hideList(event) {
if(event.relatedTarget?.parentNode !== list) {
list.classList.add("hidden");
}
}
function showSuccess(event) {
success.innerHTML = "code successful!";
// Remove line to keep list open
hideList(event);
}
#list {
display: flex;
flex-direction: column;
}
#list.hidden { display: none; }
<input id="input" />
<div id="list" class="hidden">
<a href="#">click for success</a>
<a href="#">click for more success</a>
<a href="#">click for even more success</a>
</div>
<div id="successDiv">
</div>
推荐阅读
- awk - 如何使用 sed/awk 从文件中进行数学运算
- python - Python 在将函数输出写入同一行中的列的数据帧行上应用函数
- testing - 用于测试密码注入的示例查询?
- theia - 你如何在 Theia 的 web 终端中以 sudo 运行
- r - 在两列中查找重复项
- c - scanf not getting called
- scala - mininum value of struct type column in a dataframe
- twig - 如何在 for 循环中将 n 天添加到树枝日期格式?
- docker - 码头工人副本。. 用于捆绑
- angular - 如何对 rxjs shareReplay 进行单元测试?