自己实现了一个可以进行编辑的下拉选择框,主要功能点
- 可以进行输入的下拉选择框
- 根据输入内容筛选值
- 支持上下键进行下拉内容的选择
- 支持使用Enter键确认上下键选择的内容
- 支持ESC键退出选择
下面才是重点
演示图(演示时颜色选择了经典的红绿配 -_-||| )
实现代码如下
1.测试使用页面
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>带有输入框的下拉选择框</title>
<script type="text/javascript" src="lib/jquery-3.3.1.min.js"></script>
<script type="text/javascript" src="insel.js"></script>
<link rel="stylesheet" type="text/css" href="insel.css"/>
<script type="text/javascript">
$(function(){
inselInit("country", ["日本","韩国","阿拉伯"]);
});
</script>
</head>
<body>
<input type="text" name="country" placeholder="国家" id="country" style="width: 200px;"/>
<ul id="country_insel" class="insel">
<li>中国</li>
<li>古巴</li>
<li>巴西</li>
<li>美国</li>
<li>俄罗斯</li>
</ul>
</body>
</html>
2.insel.js代码
/**
* author:guojikai
* date:2018/8/22
* */
/**
* css中单个li的高度设置,默认设置为20,查看insel.css
* Note:在更改insel.css中.insel li{height:**px};属性时同步更新该参数值
* */
var INSEL_LI_HEIGHT = 20;
/**
* css中ul下拉列表最大高度,默认为100,查看insel.css
* Note:在更改insel.css中.insel{max-height:**px};属性值时同步更新改参数值
* */
var UL_MAX_HEIGHT = 100;
/**
* 根据输入的内容自动筛选符合需求的数据值
* param id 获取需要自动提示的input框id
* param allData 所有需要筛选的数据
* */
function autoPointOut(id, allData){
//文本框id
var inId = "#"+id;
//下拉框id
var inselId = "#"+id+"_insel";
//筛选结果
var showData = [];
//当前input输入值
var curLoad=$(inId).val();
if(curLoad == ""){
//当文本框内无值时,展示所有信息
showData = allData;
}else{
//根据输入的内容筛选数据
for(var index in allData){
if(allData[index].indexOf(curLoad)!=-1){
showData.push(allData[index]);
}
}
}
//清空原列表数据
$(inselId).empty();
//展示筛选结果
for(var index in showData){
$(inselId).append("<li>"+showData[index]+"</li>");
}
//对新补充的列表数据添加事件
$(inselId+" li").mousedown(function(){
$(inId).val($(this).text());
});
}
/**
* 初始化可以进行输入的选择框
* param id 初始化的input框id
* param dataList 初始化的列表数据[数据类型为数组]
* Note:可以自行扩展通过ajax获取列表数据,进行可输入选择框下拉数据的初始化
* */
function inselInit(id, dataList){
//jquery操作的初始化input框id
var inId = "#"+id;
//jquery操作的下拉列表框id
var inselId = "#" + id +"_insel";
//将可选择数据列表纳入可选择范围内
if(dataList != undefined && (typeof dataList=='object') && dataList.constructor==Array){
for(var index in dataList){
$(inselId).append("<li>"+dataList[index]+"</li>");
}
}
//获取下拉框内所有的数据值
var dataArr = [];
var allLi = $(inselId +" li");
for(var allLiIndex=0; allLiIndex<allLi.length; allLiIndex++){
dataArr.push($(allLi[allLiIndex]).text());
}
//调整展示样式
$(inselId).width($("#"+id).width());
$(inselId).css("border", $("#"+id).css("border"));
$(inselId).css("border-color", "#EEE");
$(inselId).css("border-style", $("#"+id).css("border-style"));
$(inselId).css("padding", $("#"+id).css("padding"));
//增加事件:点击选中数据时填充至input文本框内
//Note:使用mousedown事件原因:避免blur与clock事件的冲突
$(inselId+" li").mousedown(function(){
$(inId).val($(this).text());
});
//输入文本框获取焦点时展示下拉列表数据
$(inId).focusin(function(){
$(inselId).show();
//数值4位上下边框的高度
$(inselId).offset({"top":$(inId).position().top+$(inId).height()+4, "left":$(inId).position().left});
$(inselId).css("display", "block");
$(inselId).css("position", "relative");
autoPointOut(id, dataArr);
});
//输入文本框失去焦点时隐藏下拉列表
$(inId).blur(function(){
$(inselId).hide();
});
//文本内容改变时筛选数据展示
$(inId).bind('input propertychange', function() {
autoPointOut(id, dataArr);
});
$(inId).keydown(function(e){
//当前激活数据元素
var activeLi = $(inselId+" .active").get(0);
if(e.keyCode == 38){
//上键:向上选择内容
if(activeLi==undefined){
$($(inselId+" li").last()).addClass("active");
activeLi = $(inselId+" li").last();
}else{
//清除之前的选择
$(activeLi).removeClass("active");
//为前一个数据元素设置选中状态
$(activeLi).prev().addClass("active");
//获取下一个选中的数据元素
activeLi = $(inselId+" .active").get(0);
//如果前一个选中的数据元素为undefined,说明无前一个,选中最后一个
if(activeLi == undefined){
$($(inselId+" li").last()).addClass("active");
activeLi = $(inselId+" li").last();
}
}
//设置滚动条位置
//1.根据css设置的li高度与ul最大高度,计算需要进行滚动的位置
var selIndex = $(activeLi).index()-(UL_MAX_HEIGHT/INSEL_LI_HEIGHT-1)>0?$(activeLi).index()-(UL_MAX_HEIGHT/INSEL_LI_HEIGHT-1):0;
//2.将滚动条调节至对应的位置
$(inselId).scrollTop((selIndex)*INSEL_LI_HEIGHT);
}else if(e.keyCode == 40){
//下键:向下选择内容
if(activeLi==undefined){
$($(inselId+" li").get(0)).addClass("active");
activeLi = $(inselId+" li").get(0);
}else{
//清除之前的选择
$(activeLi).removeClass("active");
//为下一个数据元素设置选中状态
$(activeLi).next().addClass("active");
//获取下一个选中的数据元素
activeLi = $(inselId+" .active").get(0);
//如果下一个选中的数据元素为undefined,说明无下一个,选中第一个
if(activeLi == undefined){
$($(inselId+" li").get(0)).addClass("active");
activeLi = $(inselId+" li").get(0);
}
}
//设置滚动条位置
//1.根据css设置的li高度与ul最大高度,计算需要进行滚动的位置
var selIndex = $(activeLi).index()-(UL_MAX_HEIGHT/INSEL_LI_HEIGHT-1)>0?$(activeLi).index()-(UL_MAX_HEIGHT/INSEL_LI_HEIGHT-1):0;
//2.将滚动条调节至对应的位置
$(inselId).scrollTop(selIndex*INSEL_LI_HEIGHT);
}else if(e.keyCode == 27){
//ESC:退出选择
$(inId).blur();
}else if(e.keyCode == 13){
//Enter:选中选择的内容到文本框内
if(activeLi!=undefined){
$(inId).val($(activeLi).text());
$(inId).blur();
$(inId).focus();
}
}
});
}
3.insel.css代码
.insel {
font-size: 14px;
list-style: none;
color: #888;
padding: 0px;
margin: 0px;
overflow-x: auto;
display: none;
/**
默认展示5个元素: 5*单个数据元素高度=最大高度
Note:该参数值维护时同步更新insel.js中UL_MAX_HEIGHT值
*/
max-height: 100px;
}
.insel li{
padding-left: 5px;
/**
单个数据元素高度
Note:该参数值维护时同步更新insel.js中INSEL_LI_HEIGHT值
*/
height: 20px;
}
.insel li:hover{
background-color: #F5F5F5;
}
.insel .active{
background-color: #F5F5F5;
}
亲测在GoogleChrome可以使用。