javascript - 如何在隐藏元素之前触发元素的事件监听器

标签 javascript html dom dom-events

我有一个输入框,当 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 上使用 mouseentermouseleave 来决定 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/

相关文章:

javascript - 如何解决 addEventListener : Cannot read property 'currentTarget' of undefined 的问题

javascript - ajax调用后使用onclick函数

javascript - Angular Carousel - <li> 元素是否需要 "position: absolute"?

javascript - 捕获 iframe 的屏幕截图

javascript - 根据另一个数组从 JavaScript 数组中删除重复项?

html - CSS类被完全忽略

javascript - 将鼠标悬停在链接上时更改 div 内容?

javascript - 在 JavaScript 中,如何将 DOM 的一部分序列化为 XHTML?

javascript - Promise.resolve 与 new Promise(resolve)

javascript - Jquery 包装元素