隨着前端功能的不斷完善帶搜索的選擇框也是迫切需要的,但是原生的搜索框不支持這個功能,所以就開發了一個
思考:怎么將代碼可以封裝到很完善,很簡潔,是函數的閉包加回調函數好,還是要面向對象的寫法好(此案例采用第一種)
重點: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;
width: 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{\
width: 100%;\
height: 100%;\
position: absolute;\
z-index: ' + selectSearchInput + '; \
box-sizing: border-box;\
top: 0;\
left: 0;\
}\
#'+dom.id +' .select-search .select-search-select{\
width: 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>
