1.点击list中内容,input的blur会先触发,导致list消失,导致list的click事件无法触发。
<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->
<!--[if gt IE 8]><!-->
<html class="no-js">
<!--<![endif]-->
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
* {
box-sizing: border-box;
}
.container {
position: relative;
width: 100px;
}
.container input {
width: 100%;
}
.list {
position: absolute;
width: 100%;
display: none;
border: 1px solid #9DC2E6;
}
.list div:hover {
background-color: #C1F5B0;
cursor: pointer;
}
</style>
</head>
<body>
<!--[if lt IE 7]>
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="#">upgrade your browser</a> to improve your experience.</p>
<![endif]-->
<div class="container">
<input list="cars" />
<datalist id="cars">
<option value="BMW">test</option>
<option value="Ford"></option>
<option value="Volvo"></option>
</datalist>
</div>
<div class="container">
<input name="text" bind="text">
<div class="list"></div>
</div>
<script>
function asyncList(dom, goodArr, filter) {
function getDisplayHtml(str) {
return ['<div>', str, '</div>'].join('');
}
const selectedArr = goodArr.filter(function (item) {
return item.includes(filter) ? true : false;
});
dom.innerHTML = selectedArr.reduce(function (prev, item) {
return prev.concat([getDisplayHtml(item)]);
}, []).join('');
}
function setDisplay(dom, display) {
display ? dom.style.display = 'block' : dom.style.display = 'none';
}
const goodArr = ['a', 'abc', 'ddff'];
const input = document.querySelector('input[name=text]');
const list = document.querySelector('.list');
input.addEventListener('input', function () {
asyncList(list, goodArr, input.value);
});
input.addEventListener('blur', function (e) {
// console.log(e.target);
setDisplay(list, false);
});
input.addEventListener('focus', function () {
asyncList(list, goodArr, input.value);
setDisplay(list, true);
});
list.addEventListener('click', function(e) {
const node = e.target;
if(node !== e.currentTarget) {
input.value = node.textContent;
}
});
</script>
</body>
</html>
这里看上去是要做一个下拉菜单对吧?
下拉菜单隐藏下拉列表可以换一种方式实现,这样就可以避免这个问题。
在window上监听click事件,出发后将菜单隐藏。当然,这个时候就要考虑点击的是菜单还是其他的位置,这个也很容易处理,有两种办法:
1是在菜单的dom上stoppropagation,这样菜单上面的点击事件就不会触发window上的回调
2是搞一个状态变量,当鼠标进入(mouseenter)的时候置为true,鼠标离开(mouseleave)的时候置为false,在window上监听的那个函数里面根据这个状态变量决定是否执行回调