zoukankan      html  css  js  c++  java
  • 带搜索框的jQuery下拉框插件

    由于下拉框的条数有几十个,于是打算找一个可以搜索查找功能的下拉框,刚开始在网上看了几个,都是有浏览器兼容性问题,后来看到这个“带搜索框的jQuery下拉框美化插件 searchable”,看演示代码简单易用,支持多个浏览器。

    不过在使用过程中碰到了几个问题,先后解决了。

    1、多个下拉框放在一起会出现遮挡的问题,原文评论有个解决方法:
    在jquery.searchableSelect.js文件里面的代码里面加上下面2行带注释的代码

    show: function() {
        this.dropdown.removeClass('searchable-select-hide');
        this.input.focus();
        this.status = 'show';
        this.setPriviousAndNextVisibility();
        this.dropdown.css('z-index', 100); //打开下拉列表时调高z-index层级  
    }, hide: function() {
        if (!(this.status === 'show')) return;
        if (this.items.find(':not(.searchable-select-hide)').length === 0) this.input.val('');
        this.dropdown.addClass('searchable-select-hide');
        this.searchableElement.trigger('focus');
        this.status = 'hide';
        this.dropdown.css('z-index', 1); //关闭下拉列表时恢复z-index层级  
    },
    

    2、原文用的是jquery-1.11.1.min.js,但是整个项目用的是jquery-1.7.2.js,在chrome浏览器F12调试一加载页面会出现错误信息:
    Uncaught TypeError: $.expr.createPseudo is not a function
    $(...).searchableSelect is not a function
    点进去提示$.expr.createPseudo有语法错误
    猜测是jquery版本问题,果然,搜索了一下,$.expr.createPseudo是jquery1.8.1版本以上支持的。
    于是修改了下代码,把下面代码

    $.expr[":"].searchableSelectContains = $.expr.createPseudo(function(arg) {
      return function( elem ) {
        return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
      };
    });
    

    修改为下面就解决:

    $.expr[":"].searchableSelectContains = function(obj,index,meta){	
    	 return $(obj).text().toUpperCase().indexOf(meta[3].toUpperCase()) >= 0;
    };
    

    3、第2个问题解决后,发现在删除搜索框文字为空时,chrome调试窗口有异常,并且下拉框不会恢复原来的下拉选项
    调试是下面这句代码有问题(如果是demo中的jquery-1.11.1.min.js版本,则不存在此问题)
    this.items.find('.searchable-select-item:searchableSelectContains('+text+')').removeClass('searchable-select-hide');
    解决方法是加一个是否为空的判断:

    if(text != ''){
    	this.items.find('.searchable-select-item:searchableSelectContains('+text+')').removeClass('searchable-select-hide');
    }else{
    	this.items.find('.searchable-select-item').removeClass('searchable-select-hide'); 
     }
    

    4、把功能整合到项目时,发现下拉框里面的搜索框被拉长变形了,chromeF12调试窗口能看到搜索框的样式有删除线,即被优先级更高的样式替换了。
    解决方法是修改jquery.searchableSelect.css里面的样式,加一个!important提高优先级

    .searchable-select-input {
      margin-top: 5px;
      border: 1px solid #ccc!important;
      outline: none;
      padding: 4px;
       100%!important;
      box-sizing: border-box;  
    }
    

    附,修改后的代码:

    demo.html

    <!DOCTYPE html>
    <html>
      <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8">
        <title>带搜索框的jQuery下拉框美化插件 searchableSelect</title>
        <link href="jquery.searchableSelect.css" rel="stylesheet" type="text/css">
        <script src="jquery-1.7.2.js"></script>
        <script src="jquery.searchableSelect.js"></script>
      </head>
      <body>
        <select id="se1">
    	  <option value="">请选择</option>
          <option value="jQuery插件库">jQuery插件库</option>
          <option value="BlackBerry">BlackBerry</option>
          <option value="device">device</option>
          <option value="with">with</option>
          <option value="entertainment">entertainment</option>
          <option value="and">and</option>
          <option value="social">social</option>
          <option value="networking">networking</option>
          <option value="apps">apps</option>
          <option value="or">or</option>
          <option value="apps">apps</option>
          <option value="that">that</option>
        </select>
        <input type="button" value="test" onclick="var v = $('#se1').val();alert(v);" />
        <script>
    		$(function(){
    			$('#se1').searchableSelect();			
    		});
        </script>
      </body>
    </html>
    

    jquery.searchableSelect.js

    // Author: David Qin
    // E-mail: david@hereapp.cn
    // Date: 2014-11-05
    
    (function($){
    
       //jQuery1.8.1以上版本使用
      // a case insensitive jQuery :contains selector
      /*$.expr[":"].searchableSelectContains = $.expr.createPseudo(function(arg) {
        return function( elem ) {
          return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0;
        };
      });*/
      
      $.expr[":"].searchableSelectContains = function(obj,index,meta){	
    	 return $(obj).text().toUpperCase().indexOf(meta[3].toUpperCase()) >= 0;
      };
      
    
      $.searchableSelect = function(element, options) {
        this.element = element;
        this.options = options || {};
        this.init();
    
        var _this = this;
    
        this.searchableElement.click(function(event){
          // event.stopPropagation();
          _this.show();
        }).on('keydown', function(event){
          if (event.which === 13 || event.which === 40 || event.which == 38){
            event.preventDefault();
            _this.show();
          }
        });
    
        $(document).on('click', null, function(event){
          if(_this.searchableElement.has($(event.target)).length === 0)
            _this.hide();
        });
    
        this.input.on('keydown', function(event){
          event.stopPropagation();
          if(event.which === 13){         //enter
            event.preventDefault();
            _this.selectCurrentHoverItem();
            _this.hide();
          } else if (event.which == 27) { //ese
            _this.hide();
          } else if (event.which == 40) { //down
            _this.hoverNextItem();
          } else if (event.which == 38) { //up
            _this.hoverPreviousItem();
          }
        }).on('keyup', function(event){
          if(event.which != 13 && event.which != 27 && event.which != 38 && event.which != 40)
            _this.filter();
        })
      }
    
      var $sS = $.searchableSelect;
    
      $sS.fn = $sS.prototype = {
        version: '0.0.1'
      };
    
      $sS.fn.extend = $sS.extend = $.extend;
    
      $sS.fn.extend({
        init: function(){
          var _this = this;
          this.element.hide();
    
          this.searchableElement = $('<div tabindex="0" class="searchable-select"></div>');
          this.holder = $('<div class="searchable-select-holder"></div>');
          this.dropdown = $('<div class="searchable-select-dropdown searchable-select-hide"></div>');
          this.input = $('<input type="text" class="searchable-select-input" />');
          this.items = $('<div class="searchable-select-items"></div>');
          this.caret = $('<span class="searchable-select-caret"></span>');
    
          this.scrollPart = $('<div class="searchable-scroll"></div>');
          this.hasPrivious = $('<div class="searchable-has-privious">...</div>');
          this.hasNext = $('<div class="searchable-has-next">...</div>');
    
          this.hasNext.on('mouseenter', function(){
            _this.hasNextTimer = null;
    
            var f = function(){
              var scrollTop = _this.items.scrollTop();
              _this.items.scrollTop(scrollTop + 20);
              _this.hasNextTimer = setTimeout(f, 50);
            }
    
            f();
          }).on('mouseleave', function(event) {
            clearTimeout(_this.hasNextTimer);
          });
    
          this.hasPrivious.on('mouseenter', function(){
            _this.hasPriviousTimer = null;
    
            var f = function(){
              var scrollTop = _this.items.scrollTop();
              _this.items.scrollTop(scrollTop - 20);
              _this.hasPriviousTimer = setTimeout(f, 50);
            }
    
            f();
          }).on('mouseleave', function(event) {
            clearTimeout(_this.hasPriviousTimer);
          });
    
          this.dropdown.append(this.input);
          this.dropdown.append(this.scrollPart);
    
          this.scrollPart.append(this.hasPrivious);
          this.scrollPart.append(this.items);
          this.scrollPart.append(this.hasNext);
    
          this.searchableElement.append(this.caret);
          this.searchableElement.append(this.holder);
          this.searchableElement.append(this.dropdown);
          this.element.after(this.searchableElement);
    
          this.buildItems();
          this.setPriviousAndNextVisibility();
        },
    
        filter: function(){
          var text = this.input.val();
          this.items.find('.searchable-select-item').addClass('searchable-select-hide');
    	  if(text != ''){
    		this.items.find('.searchable-select-item:searchableSelectContains('+text+')').removeClass('searchable-select-hide');
    	  }else{
    		this.items.find('.searchable-select-item').removeClass('searchable-select-hide'); 
    	  }
          if(this.currentSelectedItem.hasClass('searchable-select-hide') && this.items.find('.searchable-select-item:not(.searchable-select-hide)').length > 0){
            this.hoverFirstNotHideItem();
          }
    
          this.setPriviousAndNextVisibility();
        },
    
        hoverFirstNotHideItem: function(){
          this.hoverItem(this.items.find('.searchable-select-item:not(.searchable-select-hide)').first());
        },
    
        selectCurrentHoverItem: function(){
          if(!this.currentHoverItem.hasClass('searchable-select-hide'))
            this.selectItem(this.currentHoverItem);
        },
    
        hoverPreviousItem: function(){
          if(!this.hasCurrentHoverItem())
            this.hoverFirstNotHideItem();
          else{
            var prevItem = this.currentHoverItem.prevAll('.searchable-select-item:not(.searchable-select-hide):first')
            if(prevItem.length > 0)
              this.hoverItem(prevItem);
          }
        },
    
        hoverNextItem: function(){
          if(!this.hasCurrentHoverItem())
            this.hoverFirstNotHideItem();
          else{
            var nextItem = this.currentHoverItem.nextAll('.searchable-select-item:not(.searchable-select-hide):first')
            if(nextItem.length > 0)
              this.hoverItem(nextItem);
          }
        },
    
        buildItems: function(){
          var _this = this;
          this.element.find('option').each(function(){
            var item = $('<div class="searchable-select-item" data-value="'+$(this).attr('value')+'">'+$(this).text()+'</div>');
    
            if(this.selected){
              _this.selectItem(item);
              _this.hoverItem(item);
            }
    
            item.on('mouseenter', function(){
              $(this).addClass('hover');
            }).on('mouseleave', function(){
              $(this).removeClass('hover');
            }).click(function(event){
              event.stopPropagation();
              _this.selectItem($(this));
              _this.hide();
            });
    
            _this.items.append(item);
          });
    
          this.items.on('scroll', function(){
            _this.setPriviousAndNextVisibility();
          })
        },
        show: function(){
          this.dropdown.removeClass('searchable-select-hide');
          this.input.focus();
          this.status = 'show';
          this.setPriviousAndNextVisibility();
          this.dropdown.css('z-index', 100); //打开下拉列表时调高z-index层级
        },
    
        hide: function(){
          if(!(this.status === 'show'))
            return;
    
          if(this.items.find(':not(.searchable-select-hide)').length === 0)
              this.input.val('');
          this.dropdown.addClass('searchable-select-hide');
          this.searchableElement.trigger('focus');
          this.status = 'hide';
          this.dropdown.css('z-index', 1); //关闭下拉列表时恢复z-index层级
        },
    
        hasCurrentSelectedItem: function(){
          return this.currentSelectedItem && this.currentSelectedItem.length > 0;
        },
    
        selectItem: function(item){
          if(this.hasCurrentSelectedItem())
            this.currentSelectedItem.removeClass('selected');
    
          this.currentSelectedItem = item;
          item.addClass('selected');
    
          this.hoverItem(item);
    
          this.holder.text(item.text());
          var value = item.data('value');
          this.holder.data('value', value);
          this.element.val(value);
    
          if(this.options.afterSelectItem){
            this.options.afterSelectItem.apply(this);
          }
        },
    
        hasCurrentHoverItem: function(){
          return this.currentHoverItem && this.currentHoverItem.length > 0;
        },
    
        hoverItem: function(item){
          if(this.hasCurrentHoverItem())
            this.currentHoverItem.removeClass('hover');
    
          if(item.outerHeight() + item.position().top > this.items.height())
            this.items.scrollTop(this.items.scrollTop() + item.outerHeight() + item.position().top - this.items.height());
          else if(item.position().top < 0)
            this.items.scrollTop(this.items.scrollTop() + item.position().top);
    
          this.currentHoverItem = item;
          item.addClass('hover');
        },
    
        setPriviousAndNextVisibility: function(){
          if(this.items.scrollTop() === 0){
            this.hasPrivious.addClass('searchable-select-hide');
            this.scrollPart.removeClass('has-privious');
          } else {
            this.hasPrivious.removeClass('searchable-select-hide');
            this.scrollPart.addClass('has-privious');
          }
    
          if(this.items.scrollTop() + this.items.innerHeight() >= this.items[0].scrollHeight){
            this.hasNext.addClass('searchable-select-hide');
            this.scrollPart.removeClass('has-next');
          } else {
            this.hasNext.removeClass('searchable-select-hide');
            this.scrollPart.addClass('has-next');
          }
        }
      });
    
      $.fn.searchableSelect = function(options){
        this.each(function(){
          var sS = new $sS($(this), options);
        });
    
        return this;
      };
    
    })(jQuery);
    

    jquery.searchableSelect.css

    /*
    Author: David Qin
    E-mail: david@hereapp.cn
    Date: 2014-11-05
    */
    
    .searchable-select-hide {
      display: none;
    }
    
    .searchable-select {
      display: inline-block;
      min- 130px;
      font-size: 14px;
      line-height: 1.428571429;
      color: #555;
      vertical-align: middle;
      position: relative;
      outline: none;  
    }
    
    .searchable-select-holder{
      padding: 2px;
      background-color: #fff;
      background-image: none;
      border: 1px solid #ccc;
      border-radius: 2px;
      min-height: 30px;
      box-sizing: border-box;
      -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
      box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
      -webkit-transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
      transition: border-color ease-in-out .15s,box-shadow ease-in-out .15s;
    }
    
    .searchable-select-caret {
      position: absolute;
       0;
      height: 0;
      box-sizing: border-box;
      border-color: black transparent transparent transparent;
      top: 0;
      bottom: 0;
      border-style: solid;
      border- 5px;
      margin: auto;
      right: 10px;
    }
    
    .searchable-select-dropdown {
      position: absolute;
      background-color: #fff;
      border: 1px solid #ccc;
      border-bottom-left-radius: 4px;
      border-bottom-right-radius: 4px;
      padding: 4px;
      border-top: none;
      top: 28px;
      left: 0;
      right: 0;
    }
    
    .searchable-select-input {
      margin-top: 5px;
      border: 1px solid #ccc;
      outline: none;
      padding: 4px;
       100%;
      box-sizing: border-box;
       100%;
    }
    
    .searchable-scroll {
      margin-top: 4px;
      position: relative;
    }
    
    .searchable-scroll.has-privious {
      padding-top: 16px;
    }
    
    .searchable-scroll.has-next {
      padding-bottom: 16px;
    }
    
    .searchable-has-privious {
      top: 0;
    }
    
    .searchable-has-next {
      bottom: 0;
    }
    
    .searchable-has-privious, .searchable-has-next {
      height: 16px;
      left: 0;
      right: 0;
      position: absolute;
      text-align: center;
      z-index: 10;
      background-color: white;
      line-height: 8px;
      cursor: pointer;
    }
    
    .searchable-select-items {
      max-height: 400px;
      overflow-y: scroll;
      position: relative;
    }
    
    .searchable-select-items::-webkit-scrollbar {
      display: none;
    }
    
    .searchable-select-item {
      padding: 5px 5px;
      cursor: pointer;
      min-height: 30px;
      box-sizing: border-box;
        transition: all 1s ease 0s;
    }
    
    .searchable-select-item.hover {
    
      background: #555;
      color: white;
    }
    
    .searchable-select-item.selected {
      background: #28a4c9;
      color: white;
    }
    

      

  • 相关阅读:
    注册课程程序
    WEB_03
    JAVAWEB学习 HTML&CSS
    JAVAWEB -HTML学习
    二柱子——四则运算——王建民
    JAVA假期第十三天2020年7月18日
    JAVA假期第十二天2020年7月17日
    JAVA假期第十四天2020年7月19日
    JAVA假期第十一天2020年7月16日
    数据库规约
  • 原文地址:https://www.cnblogs.com/gdjlc/p/7744157.html
Copyright © 2011-2022 走看看