zoukankan      html  css  js  c++  java
  • js,JQuery实现,带筛选,搜索的select

    代码

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>网上找了个插件,但是不好用</title>
        <script src="jquery.js" charset="utf-8"></script>
        <style>
            body,html{padding:0;margin:0;width:100%;height:100%;}
        </style>
    </head>
    <body>
        <div style="height:500px;margin:20px;">
            <!-- option必须带有 value 的值 -->
            <select id="magicsuggest" data-edit-select="1">
                <option value="1">哇哈哈</option>
                <option value="2">天天</option>
                <option value="3">xx</option>
                <option value="1">哇哈哈哇哈哈哇哈哈哇哈哈哇哈哈</option>
                <option value="2">天天</option>
                <option value="3">xx</option>
                <option value="1">哇哈哈</option>
                <option value="2">天天</option>
                <option value="3">xx</option>
                <option value="1">哇哈哈</option>
                <option value="2">天天</option>
                <option value="3">xx</option>
            </select>
        </div>
        <div style="height:1000px;"></div>
    </body>
    
    <!-- 下面这段代码,就是可编辑select,嗯,那个丑陋的样式,被我也写在里面了 -->
    <script type="text/javascript">
    $.fn.filterSelect = (function(){
        // 我就 很 纠结的,把样式内嵌在这里了,让你怎么改!!!!
        var isInit = false;
        function initCss(){
            isInit = true;
            var style = document.createElement("style");
            var csstext = '.m-input-select{display:inline-block;*display:inline;position:relative;-webkit-user-select:none;}
                            
    .m-input-select ul, .m-input-select li{padding:0;margin:0;}
                            
    .m-input-select .m-input{padding-right:22px;}
                            
    .m-input-select .m-input-ico{position:absolute;right:0;top:0;22px;height:100%;background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAAATElEQVQoU2NkIBEwkqiegTwNcXFx/4m1CW4DMZoWLVrEiOIkfJpAikGuwPADNk0wxVg1gASRNSErxqkBpgldMV4NuEKNvHggNg5A6gBo4xYmyyXcLAAAAABJRU5ErkJggg==) no-repeat 50% 50%;}
                            
    .m-input-select .m-list-wrapper{}
                            
    .m-input-select .m-list{display:none;position:absolute;z-index:1;top:100%;left:0;right:0;max-100%;max-height:250px;overflow:auto;border-bottom:1px solid #ddd;}
                            
    .m-input-select .m-list-item{cursor:default;padding:5px;margin-top:-1px;list-style:none;background:#fff;border:1px solid #ddd;border-bottom:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}
                            
    .m-input-select .m-list-item:hover{background:#2D95FF;}
                            
    .m-input-select .m-list-item-active{background:#2D95FF;}';
            style = $("<style>"+ csstext +"</style>")[0];
            // ie 竟然坑了...
            // if(style.styleSheet) {
            //     style.styleSheet.cssText = csstext;
            // }else{
            //     style.appendChild(document.createTextNode(csstext));
            // };
    
            var head = document.head || document.getElementsByTagName("head")[0];
            if(head.hasChildNodes()){
                head.insertBefore(style, head.firstChild);
            }else{
                head.appendChild(style);
            };
    
        };
    
        return function(){
            !isInit && initCss();
    
            var $body = $("body");
            this.each(function(i, v){
                var $sel = $(v), $div = $('<div class="m-input-select"></div>');
                var $input = $("<input type='text' class='m-input' />");
                // var $wrapper = $("<div class='m-list-wrapper'><ul class='m-list'></ul></div>");
                var $wrapper = $("<ul class='m-list'></ul>");
                $div = $sel.wrap($div).hide().addClass("m-select").parent();
                $div.append($input).append("<span class='m-input-ico'></span>").append($wrapper);
    
                // 遮罩层显示 + 隐藏
                var wrapper = {
                    show: function(){
                        $wrapper.show();
                        this.$list = $wrapper.find(".m-list-item:visible");
                        this.setIndex(this.$list.filter(".m-list-item-active"));
                        this.setActive(this.index);
                    },
                    hide: function(){
                        $wrapper.hide();
                    },
                    next: function(){
                        return this.setActive(this.index + 1);
                    },
                    prev: function(){
                        return this.setActive(this.index - 1);
                    },
                    $list: $wrapper.find(".m-list-item"),
                    index: 0,
                    $cur: [],
                    setActive: function(i){
                        // 找到第1个 li,并且赋值为 active
                        var $list = this.$list, size = $list.size();
                        if(size <= 0){
                            this.$cur = [];
                            return;
                        }
                        $list.filter(".m-list-item-active").removeClass("m-list-item-active");
                        if(i < 0){
                            i = 0;
                        }else if(i >= size){
                            i = size - 1;
                        }
                        this.index = i;
                        this.$cur = $list.eq(i).addClass("m-list-item-active");
                        this.fixScroll(this.$cur);
                        return this.$cur;
                    },
                    fixScroll: function($elem){
                        // console.log($wrapper);
                        var height = $wrapper.height(), top = $elem.position().top, eHeight = $elem.outerHeight();
                        var scroll = $wrapper.scrollTop();
                        // 因为 li 的 实际 top,应该要加上 滚上 的距离
                        top += scroll;
                        if(scroll > top){
                            $wrapper.scrollTop(top);
                        }else if(top + eHeight > scroll + height){
                            // $wrapper.scrollTop(top + height - eHeight);
                            $wrapper.scrollTop(top + eHeight - height);
                        }
                    },
                    setIndex: function($li){
                        if($li.size() > 0){
                            this.index = this.$list.index($li);
                            $li.addClass("m-list-item-active").siblings().removeClass("m-list-item-active");
                        }else{
                            this.index = 0;
                        }
                    }
                };
    
                // input 的操作
                var operation = {
                    // 文字更变了,更新 li, 最低效率的一种
                    textChange: function(){
                        val = $.trim($input.val());
                        $wrapper.find(".m-list-item").each(function(i, v){
                            if(v.innerHTML.indexOf(val) >= 0){
                                $(v).show();
                            }else{
                                $(v).hide();
                            }
                        });
                        wrapper.show();
                    },
                    // 设值
                    setValue: function($li){
                        if($li && $li.size() > 0){
                            var val = $.trim($li.html());
                            $input.val(val).attr("placeholder", val);
                            wrapper.setIndex($li);
                            $sel.val($li.attr("data-value")).trigger("change");
                        }else{
                            $input.val(function(i, v){
                                return $input.attr("placeholder");
                            });
                        };
                        wrapper.hide();
                        this.offBody();
                    },
                    onBody: function(){
                        var self = this;
                        setTimeout(function(){
                            self.offBody();
                            $body.on("click", self.bodyClick);
                        }, 10);
                    },
                    offBody: function(){
                        $body.off("click", this.bodyClick);
                    },
                    bodyClick: function(e){
                        var target = e.target;
                        if(target != $input[0] && target != $wrapper[0]){
                            wrapper.hide();
                            operation.setValue();
                            operation.offBody();
                        }
                    }
                };
    
                // 遍历 $sel 对象
                function resetOption(){
                    var html = "", val = "";
                    $sel.find("option").each(function(i, v){
                        if(v.selected && !val){
                            val = v.text;
                        };
                        html += '<li class="m-list-item'+ (v.selected ? " m-list-item-active" : "") +'" data-value="'+ v.value +'">'+ v.text +'</li>';
                    });
                    $input.val(val);
                    $wrapper.html(html);
                };
                $sel.on("optionChange", resetOption).trigger("optionChange");
                $sel.on("setEditSelectValue", function(e, val){
                    // console.log(val);
                    var $all = $wrapper.find(".m-list-item"), $item;
                    for(var i = 0, max = $all.size(); i < max; i++){
                        $item = $all.eq(i);
                        if($item.attr("data-value") == val){
                            operation.setValue($item);
                            return;
                        }
                    }
                });
    
                // input 聚焦
                $input.on("focus", function(){
                    this.value = "";
                    operation.textChange();
                    operation.onBody();
                }).on("input propertychange", function(e){
                    operation.textChange();
                }).on("keydown", function(e){
                    // 上 38, 下 40, enter 13
                    switch(e.keyCode){
                        case 38:
                            wrapper.prev();
                            break;
                        case 40:
                            wrapper.next();
                            break;
                        case 13:
                            operation.setValue(wrapper.$cur);
                            break;
                    }
                });
    
                $div.on("click", ".m-input-ico", function(){
                    // 触发 focus 和 blur 事件
                    // focus 是因为 input 有绑定
                    // 而 blur,实际只是失去焦点而已,真正隐藏 wrapper 的是 $body 事件
                    $wrapper.is(":visible") ? $input.blur() : ($input.val("").trigger("focus"));
                });
    
                // 选中
                $wrapper.on("click", ".m-list-item", function(){
                    operation.setValue($(this));
                    return false;
                });
    
                setTimeout(function(){
                    // for ie
                    wrapper.hide();
                }, 1)
    
    
            });
    
            return this;
        };
    })();
    </script>
    
    
    <!-- 这段代码,是遍历所有拥有 data-edit-select 属性的元素,并把他们变为可编辑 -->
    <script>
    // 使用了这个插件,select该怎么用就怎么用
    // 任何选择,同样会触发 select 的 更变的说【即select的值会同步更新】
    //
    var $select = $("select[data-edit-select]").filterSelect();
    // --> 这时候的  $select === $("#magicsuggest");
    // 也可以 用 $("#magicsuggest").on("change"),两者等价
    $select.on("change", function(){
        // console.log(this.value)
    });
    // 也可以通过 $("#magicsuggest").val() 拿到最新的值
    // 通过 $("#magicsuggest").trigger("setEditSelectValue", 2); 设置选中的值为 2
    // 通过 $("#magicsuggest").trigger("optionChange") 触发 更新 option 的值
    </script>
    </html>

    源地址:https://blog.csdn.net/linfenpan/article/details/48750889

  • 相关阅读:
    ubuntu 20.04 安装mysql
    vim 编辑器常用命令备份
    各个Iot Cloud对MQTT协议的支持
    Linux下sleep函数与usleep函数加Windows下的Sleep函数
    localtime、localtime_s、localtime_r的使用
    Windows平台下利用openssl配置产生SSL认证文件
    转载
    转载- 常见arduino型号(版本)比较
    转载
    转载
  • 原文地址:https://www.cnblogs.com/wangzhaobo/p/8984135.html
Copyright © 2011-2022 走看看