Javascript:如何在隐藏元素之前触发元素上的事件侦听器

时间:2017-09-22 17:18:19

标签: javascript html dom javascript-events

我有一个输入框,当焦点事件触发时,输入框下方会显示一个提示文字列表,当触发模糊事件时,列表将被隐藏。

我在提示列表中添加了click事件监听器,但是当我尝试单击提示时,输入框上的blur事件首先被触发,因此提示上的click事件永远不会被触发。

有没有办法先在提示文字上点击事件?之后,我将触发模糊事件处理程序以隐藏提示文本。

'<meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <link rel="shortcut icon" href="assets/favicon/favicon.ico" type="image/x-icon"/>
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;
}

3 个答案:

答案 0 :(得分:2)

您可以使用mouseenter上的mouseleavelistEl来确定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。例如,您可以设置display: block列表,input正在悬停时,或者是焦点;或者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>

答案 1 :(得分:1)

onmousedown会阻止列表隐藏,而不是点击。

var textEl = document.getElementById("text"),
  listEl = document.getElementById("list");

textEl.onfocus = function() {
  listEl.style.display = "initial";
}

textEl.onblur = function() {
  listEl.style.display = "none";
}

listEl.onmousedown = 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>

答案 2 :(得分:1)

您必须将 onclick 更改为 onmousedown ,它将在模糊事件之前触发。

listEl.onmousedown = function(event) {
  var item = event.target;
  alert(item.textContent);
  textEl.value = item.textContent;
}

试试这个代码段

var textEl = document.getElementById("text"),
  listEl = document.getElementById("list");

textEl.onfocus = function() {
  listEl.style.display = "initial";
}

textEl.onblur = function() {
  listEl.style.display = "none";
}

listEl.onmousedown = 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>