zoukankan      html  css  js  c++  java
  • 原生 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;
                     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>
  • 相关阅读:
    基础操作
    需要注意
    简单操作
    git指令-版本回退
    设计模式-代理模式
    在idea下遇到的问题汇总
    maven笔记--持续更新
    poi简介
    Win10添加右键在此处打开命令行
    Ajax&Json案例
  • 原文地址:https://www.cnblogs.com/shangjun6/p/15414807.html
Copyright © 2011-2022 走看看