需求:实现可搜索的选择列表,点击确认按钮把选中结果打印输出(编程环境:小程序、H5皆可,页面不作强性要求)。
效果图如下:
解决思路:
(1)首先设置一个input框,让用户输入搜索内容
(2)然后利用div+p充当下拉框,先隐藏起来
(3)再对input添加onfocus事件,当input获取焦点时显示下拉框, 添加onblur事件,当input失去焦点时隐藏下拉框
(4)input添加oninput事件,根据用户输入内容筛选有关p标签这里使用防抖技术,
(5)对p标签进行点击事件的监听,将用户选择的内容显示在搜索框内
在实现时,遇到一个问题,点击事件本来想用onclick,但是onclick和onblur事件会存在冲突:当input输入框绑定onblur事件,input输入框的下拉事件里需要单击onclick绑定input数据。在点击下拉框数据的同时,input也失去了焦点,所以会触发onblur事件,并且onblur会优先于onclick执行。这就会导致下拉框数据的onclick事件无法正确执行。
这里我采取的解决方案是:将onclick替换为onmousedown,会先执行onmousedown事再执行onblur事件
源代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<style>
input {
width: 300px;
height: 30px;
border-radius: 25px;
}
#btn #btn2{
width: 50px;
height: 30px;
}
#select {
width: 300px;
height: 200px;
background-color: darkgray;
visibility: hidden;
overflow: scroll;
}
</style>
<body>
<!-- 需求描述:实现可搜索的选项列表, 点击确认按钮把选中结果打印出来-->
<!-- 思路:
(1)首先设置一个input框,让用户输入搜索内容
(2)然后利用div+p充当下拉框,先隐藏起来
(3)再对input添加onfocus事件,当input获取焦点时显示下拉框, 添加onblur事件,当input失去焦点时隐藏下拉框
(4)input添加oninput事件,根据用户输入内容筛选有关p标签这里使用防抖技术,
(5)对p标签进行onmousedown事件的监听,将用户选择的内容显示在搜索框内
-->
<input type="text" id="searchInput" value="请选择您的开户银行">
<button id="btn">搜索</button>
<button id="btn2">确认</button>
<div id="select">
</div>
</body>
<script>
// 数据源
let data = [
{
id: 1,
name: '中国工商银行'
},
{
id: 2,
name: '中国建设银行'
},
{
id: 3,
name: '中国农业银行'
},
{
id: 4,
name: '中国银行'
},
{
id: 5,
name: '交通银行'
},
{
id: 6,
name: '招商银行'
},
{
id: 7,
name: '上海浦发发展银行'
},
{
id: 8,
name: '中国民生银行'
},
{
id: 9,
name: '深圳发展银行'
},
{
id: 10,
name: '广东发展银行'
},
{
id: 11,
name: '中信银行'
}
];
let input = document.getElementById('searchInput');
let select = document.getElementById('select');
let btn2 = document.getElementById('btn2')
for (const iterator of data) {
let element = document.createElement('p')
element.innerHTML = iterator.name
select.appendChild(element)
}
function debounce(fn, delay) {
let timer = null;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
fn.apply(this, arguments);
}, delay);
};
}
function filterOptions() {
let keyword = input.value.trim().toLowerCase();
let options = Array.from(select.getElementsByTagName('p'));
options.forEach((option) => {
let optionText = option.innerText.toLowerCase();
if (optionText.includes(keyword)) {
option.style.display = 'block';
} else {
option.style.display = 'none';
}
});
}
input.onfocus = () => {
select.style.visibility = 'visible';
};
input.onblur = () => {
select.style.visibility = 'hidden';
};
input.oninput = debounce(filterOptions, 300);
select.onmousedown = (event) => {
let selectedOption = event.target.innerText;
input.value = selectedOption;
};
btn2.onclick = function(){
console.log(input.value)
}
</script>
</html>