原生 select 帶搜索功能


  隨着前端功能的不斷完善帶搜索的選擇框也是迫切需要的,但是原生的搜索框不支持這個功能,所以就開發了一個

  思考:怎么將代碼可以封裝到很完善,很簡潔,是函數的閉包加回調函數好,還是要面向對象的寫法好(此案例采用第一種)

  重點: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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM