0%

click blur 执行顺序问题

2018.12.15 15:27 ES6学习中

Thejsway/chapter17 Coding time <Autocomplete>

原题:

Autocomplete

In this exercise, you’ll have to assist the user in selecting a country. As he enters the country name in an input box, the page shows a list of corresponding countries. Clicking on a suggested country replaces the value in the input box.

To keep things simple, only countries starting with a “A” letter are taken into account.

Here is the HTML code that creates the input box.

<label for="country">Enter a country name</label>:
<input type="text" id="country">
<div id="suggestions"></div>

The following CSS code improves the page presentation.

/* Add spacing between each country suggestion */
.suggestion {
  padding-left: 2px;
  padding-right: 2px;
}

/* Change suggestion color when hovering it with the mouse */
.suggestion:hover {
  background-color: #adf;
  cursor: pointer;
}

/* Position the suggestion list just below the input box */
#suggestions {
  position: absolute;
  border: 1px solid black;
  left: 180px;
  width: 145px;
}

Complete this code to implement country autocompletion.

img

我的js代码:

const countryList = [
  "Afghanistan",
  "Albania",
  "Algeria",
  "Andorra",
  "Angola",
  "Anguilla",
  "Antarctica",
  "Antigua-and-Barbuda",
  "Argentina",
  "Armenia",
  "Aruba",
  "Australia",
  "Autria",
  "Azerbaïjan"
];
window.onload = function(){
  document.getElementById("suggestions").style.display = "none";
  for(const some of countryList){
    const newli = document.createElement("li");
    newli.textContent = some;
    newli.style.listStyle = "none";
    newli.style.display = "none";
    newli.className = "suggestion";
    document.getElementById("suggestions").appendChild(newli);
  }
  document.getElementById("suggestions").addEventListener("click", e => {
    const neirong = e.target.textContent;
    document.getElementById("country").value = neirong;
    document.getElementById("suggestions").style.display = "none";
  })
};
document.getElementById("country").addEventListener("input", e => {
  document.getElementById("suggestions").style.display = "block";
  const input = e.target.value;
  const lists = document.getElementsByTagName("li");
  for(const one of lists){
    if(one.textContent.startsWith(input)){
      one.style.display = "block";
    } else {
      one.style.display = "none";
    }
  }
});
document.getElementById("country").addEventListener("blur", e => {
  setTimeout(nonefun, "100");
});
function nonefun(){
  document.getElementById("suggestions").style.display = "none";
}

效果基本实现,发现click 与blur存在顺序问题,若不设置延时,则click效果无法实现。
Click后执行而无法实现效果的原因暂时不知。
看到一篇相关文章: 传送门

2020年的回顾

代码好像已经找不到了,尝试直接复现一下。不知道是不是漏了什么,笔记中的代码无法实现需要的效果。

仔细看了看,是我输错了关键词……

看了一下当时遇到的问题,其实最近也遇到了一次。

当时的情况是 A 元素绑定了一个点击事件,需要对点击做出响应,而 B 元素(往往是与该元素相关联的元素)又会响应 blur 事件,在响应 blur 的时候会隐藏 A 元素。

而点击 A元素就是 B 元素的 blur 事件,于是在 A 元素响应点击之前,就已经被隐藏了。

因此我们需要在触发 blur 的地方延迟隐藏,让它可以先响应 click 事件。