随着前端功能的不断完善带搜索的选择框也是迫切需要的,但是原生的搜索框不支持这个功能,所以就开发了一个
思考:怎么将代码可以封装到很完善,很简洁,是函数的闭包加回调函数好,还是要面向对象的写法好(此案例采用第一种)
重点:select 标签 html5 新增的 size 属性
只要将此代码复制粘贴即可查看效果
实现思路:select方法,向外暴露了两个方法,一个是setData 填充数据,一个是curData 查看选中数据,
select有两个参数,一个是dom元素,一个是配置内容
初始时,会将固定的内容拼接到dom元素下面,配置内容分为两种,一种是固定的内容,一种是回调函数的内容,我还为了省事,将dom元素下的input 元素 及 select 元素暴露出去,
从而进行dom操作来满足大部分的业务需求,
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
}
#demo1{
margin-top: 20px;
margin-left: 20px;
300px;
height: 20px;
}
</style>
</head>
<body>
<button onclick="fn()"> 获取 </button>
<div id="demo1"></div>
</body>
<script>
// dom 元素,obj 配置
function select(dom, obj){
function init(){
if(!window.selectSearchInput){
window.selectSearchInput = 500;
}
window.selectSearchInput -= 2;
var selectSearchInput = window.selectSearchInput
if(obj.selectSearchInput){
selectSearchInput = obj.selectSearchInput
}
var style = document.createElement('style');
style.innerHTML = '#'+dom.id +' .select-search{
position: relative;
height: 100%;
}
#'+dom.id +' .select-search .select-search-input{
100%;
height: 100%;
position: absolute;
z-index: ' + selectSearchInput + ';
box-sizing: border-box;
top: 0;
left: 0;
}
#'+dom.id +' .select-search .select-search-select{
100%;
position: absolute;
z-index: ' + selectSearchInput + ';
top: 0;
left: 0;
outline: none;
}
#'+dom.id +' .select-search .select-search-select option{
height: '+ dom.offsetHeight +'px;
cursor: pointer;
}
#'+dom.id +' .select-search .select-search-select option:hover{
color: #fff;
background: #5897fb;
}'
var ref = document.querySelector('script');
ref.parentNode.insertBefore(style, ref);
var str = '';
str += '<div class="select-search">
<select size="0" class="select-search-select"></select>
<input type="text" class="select-search-input">
</div>'
dom.innerHTML = str;
}
init();
// input 元素操作
var input = dom.getElementsByClassName('select-search-input')[0];
// select 元素操作
var select = dom.getElementsByClassName('select-search-select')[0];
// 数据源
var datasoure = [];
// 当前数据
var currsoure = [];
// 事件触发
var time = null;
if(obj.input){
obj.input(input);
}
if(obj.select){
obj.select(select);
}
// 填充select的数据
function selectData(data){
var str = '<option> 占位符 </option>';
for(var i=0;i<data.length;i++){
str += '<option value='+data[i].id+' indexKey='+ data[i].indexKey +'> '+ data[i].text +' </option>';
}
select.innerHTML = str;
}
// 设置 data
function setData(data){
for(var i=0;i<data.length;i++){
data[i].indexKey = i;
}
datasoure = data;
if(obj.isSelectHtml){
select.innerHTML = data;
} else {
selectData(data);
}
}
// 获取当前选中状态
function curData(){
return currsoure;
}
// 点击展开select标签
input.onfocus = function(e){
select.setAttribute('size', obj.size? obj.size : '7');
}
// input失焦关闭select标签
input.onblur = function(e){
setTimeout(function() {
select.setAttribute('size', '');
}, 250)
}
// 实时获取input值
input.oninput = function(e){
// 延迟执行,防止一直调接口
if(time!=null){
clearTimeout(time)
}
time=setTimeout(function(){
var val = e.target.value;
currsoure = [];
if(obj.isRequest){
obj.search(val);
}
else {
var patty = new RegExp(val);
var arr = []
for(var i=0;i<datasoure.length;i++){
if(patty.test(datasoure[i].text)){
arr.push(datasoure[i])
}
}
selectData(arr);
}
},obj.delay? obj.delay: 500)
}
// 获取选择是值
select.onchange = function(e){
var option = dom.getElementsByTagName('option');
var str = ''
currsoure = [];
for(var i=1;i<option.length;i++){
if(option[i].selected){
var indexKey = option[i].getAttribute('indexKey')
currsoure.push(datasoure[indexKey]);
str += datasoure[indexKey].text + ',';
}
}
input.value = str.slice(0,str.length-1);
this.setAttribute('size', '0');
}
return {
setData, // 设置数据
curData, // 获取选中内容
}
}
var arr = [];
for(var i=0;i<50;i++){
arr.push({
id: i+'',
text: '这是对应的值'+i
})
}
var config = select(document.getElementById('demo1'), {
size: '7', // 展示的数据
selectSearchInput: 500, // 自定义z-index
delay: 500, // 延迟时间
isRequest: false, // 是否自定义搜索
isSelectHtml: false, // 是否自定义option内容
input: function(e){ // input 的dom操作
// console.log(e)
e.setAttribute('placeholder','请选择内容')
},
select: function(e){ // select 的dom操作
// console.log(e);
},
search: function(e){ // 带搜索
config.setData(arr);
},
})
config.setData(arr);
function fn(){
console.log(config.curData());
}
</script>
</html>
在安利一个小技巧
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<input type="text" id="input">
</body>
<script>
var input = document.getElementById('input');
function fn(dom) {
function on(event, handler){
dom[event] = handler
}
return {
on
};
}
var f = fn(input);
f.on('oninput',function(e){
console.log(e);
})
</script>
</html>