隨着前端功能的不斷完善帶搜索的選擇框也是迫切需要的,但是原生的搜索框不支持這個功能,所以就開發了一個
思考:怎么將代碼可以封裝到很完善,很簡潔,是函數的閉包加回調函數好,還是要面向對象的寫法好(此案例采用第一種)
重點: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>