同时触发两个事件时如何控制执行顺序

时间:2020-09-21 11:37:26

标签: javascript html drop-down-menu

这是一个简单的下拉菜单,其中包含/usr/local/miniconda3/conda.exe: error while loading shared libraries: libz.so.1: failed to segment from sh ared object: Operation not permitted /usr/local/miniconda3/conda.exe: error while loading shared libraries: libz.so.1: failed to segment from sh ared object: Operation not permitted 的HTML和纯javascript(无JQuery)。我不想将预定义的HTML列表与选项标签一起使用,因为我需要滚动条,样式等。

我隐藏了列表input,但是此事件在单击项目列表之前被触发。因此结果是我无法单击下拉菜单的项目,因为该列表已被隐藏。

这是代码:

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; }

1 个答案:

答案 0 :(得分:1)

最简单的解决方案是在隐藏元素之前用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>

编辑:更强大的解决方案

您可以查看事件relatedTarget,如果它在列表中,请在单击之前将其关闭。

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>