目录
背景:
搜索框中需要使用到动态获取热点搜索历史的功能,此时需要自定义下拉列表。select组件不能完全满足要求。
搜索框下拉列表支持键盘上下键及回车选择,也支持鼠标单击选择,功能与select组件类似。
效果:
注意事项:
1、引用的 jquery请根据需要重新设置(可引用本地文件或服务器文件):
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js">
2、尽量避免使用全局监听,应使用局部监听。因为全局监听事件很容易与局部组件监听事件冲突,需要特别注意,不得已的情况下全局监听事件中可增加排除(避免影响局部监听)判断。
例如:
if ( ($("#city_list").css("display") == "block") && ($(target).attr("id") && $(target).attr("id")!="city_input" ) )
3、鼠标键盘事件的使用让开发更灵活,但也需要更多的代码来实现。同样的下拉列表,使用select组件就简单得多。请参见:CSDNhttps://mp.csdn.net/mp_blog/creation/editor/122902336
4、输入框改为回车监听更适合搜索框场景,本文为了简化操作,使用的鼠标单击显示下拉列表:
//输入框绑定单击事件,显示下拉列表
$("#city_input").on("click", function(event){
event.preventDefault();
//alert("输入框被点击了。");
$.fn.show_list(); //获取城市列表并显示到下拉列表中
});
完整代码:
<html>
<head>
<script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js">
</script>
<title>自定义下拉列表</title>
<style>
/* 输入框样式 */
#city_input{
width: 9rem;
}
/* 下拉列表样式 */
.div_list {
width: 12rem;
border-radius: 0.3rem;
border: 1px solid #ccc;
box-shadow: 0 1px 6px 0 rgb(0 0 0 / 15%);
box-sizing: border-box;
}
/* 下拉列表每一个选项样式*/
.a_city:hover {
background-color: #0DC;
color: #fff;
}
.hover {
background-color: #0DC;
color: #fff;
}
</style>
</head>
<body id="my_body">
<form id="myform">
城市: <input id="city_input" type="text" name="citys" autocomplete="off" >
<div id="city_list" style="display:none" class="div_list"></div>
<form>
<body>
<script>
var citys = ["北京", "上海", "广州", "深圳"];
//定义函数:获取城市列表并显示到下拉列表中
$.fn.show_list = function(){
var eles_city = "";
//获取城市列表,构造选项添加到ele_city_list中,作为子节点。
for(let item of citys) {
console.log(item);
ele_a_city = '<div class="a_city">'+ item + '</div>'
eles_city = eles_city.concat(ele_a_city); //字符串拼接,或者使用 +,不能像Python一样 +=,
}
$("#city_list").html(eles_city);
$("#city_list").css("display", "block");
};
//输入框绑定单击事件,显示下拉列表
$("#city_input").on("click", function(event){
event.preventDefault();
//alert("输入框被点击了。");
$.fn.show_list(); //获取城市列表并显示到下拉列表中
});
//城市列表中的每一个元素(div)绑定单击事件,将值填入输入框中
$("#city_list").on("click", "div", function(){
//alert("选项被点击了。");
//console.log(this.innerText);
$("#city_input").val(this.innerText);
$("#city_list").css("display", "none"); //隐藏下拉列表
});
//监听键盘事件,支持方向键(上下滚动)和回车键(选择选项)
$("#city_input").on('keydown',function(event){ //监听事件尽量不用 "body" 或 document ,精确到具体组件
if ($("#city_list").css("display") == "block"){
event.preventDefault();//阻止元素发生默认的行为(默认回车后会清空输入框)
var upDownClickNum = $("#city_list .hover ").length; //当前悬浮的选项个数
//alert(obj.innerText)
switch(event.keyCode) {
case 13: //回车选择选项
var selectd_items = $("#city_list .hover");
if (selectd_items[0]){
$("#city_input").val(selectd_items[0].innerText);
//alert(selectd_items[0].innerText)
$("#city_list").css("display", "none"); //隐藏下拉列表
}
break;
case 38:
//alert("键盘事件,向上。");
if (upDownClickNum < 1) {
$("#city_list div:last").addClass("hover");
} else {
$("#city_list .hover").removeClass("hover").prev().addClass("hover");
}
break;
case 40:
//alert("键盘事件,向下。");
if (upDownClickNum < 1) {
$("#city_list div:first").addClass("hover");
} else {
$("#city_list .hover").removeClass("hover").next().addClass("hover");
}
break;
defaults:
return;
}
}
});
//监听全局( document )的鼠标单击事件,隐藏下拉列表
$(document).on("click", function(event){
var e = event || window.event //event兼容写法
var target = e.target || e.srcElement //target兼容写法
if ( ($("#city_list").css("display") == "block") && ($(target).attr("id") && $(target).attr("id")!="city_input" ) ){
$("#city_list").css("display", "none"); //隐藏下拉列表
//$("#city_list").hide(); // 功能相同:隐藏组件
}
});
</script>
</html>