由于下拉框的条数有几十个,于是打算找一个可以搜索查找功能的下拉框,刚开始在网上看了几个,都是有浏览器兼容性问题,后来看到这个“带搜索框的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;
width: 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-width: 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;
width: 0;
height: 0;
box-sizing: border-box;
border-color: black transparent transparent transparent;
top: 0;
bottom: 0;
border-style: solid;
border-width: 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;
width: 100%;
box-sizing: border-box;
width: 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;
}

  

带搜索框的jQuery下拉框插件的更多相关文章

  1. 带搜索框的select下拉框

    利用select2制作带有搜索功能的select下拉框 1.引入线上css和js <link href="https://cdnjs.cloudflare.com/ajax/libs/ ...

  2. jquery 下拉框 收藏

    jquery 下拉框  Query获取Select选择的Text和Value: 语法解释: 1. $("#select_id").change(function(){//code. ...

  3. jQuery下拉框操作系列$("option:selected",this) &&(锋利的jQuery)

    jQuery下拉框操作系列$("option:selected",this)  &&(锋利的jQuery) <!DOCTYPE html> <ht ...

  4. Ajax jQuery下拉框联动案例

    需求: 使用ajax和jQuery实现下拉框联动. 注意:需要加入jquery-2.1.1.min.js 前台 <!DOCTYPE html> <html> <head& ...

  5. firefox浏览器中 bootstrap 静态弹出框中select下拉框不能弹出(解决方案)

    问题出现场景1: 在firefox浏览器中在bootstrap弹出的modal静态框中再次弹出一个静态框时 select下拉框不能弹出选项 解决方案:去掉最外层静态框的 tabindex=" ...

  6. jquery 下拉框插件,实现智能补全,模糊搜索,多选

    近期已朋友问我问题,实现类似淘宝百度的下啦搜索条,看了网上好多帖子,都看起来好复杂,而且引用了好多没用的东西,而且多选选择内容多之后容易样式奔溃, 无奈之下只好自己改了, 话不多说上效果图: 模糊搜索 ...

  7. datagrid在MVC中的运用05-加入时间搜索条件,枚举填充下拉框

    本文主要来体验在搜索区域增加更多的搜索条件,主要包括: ※ 使用jQuery ui的datepicker显示时间,设置显示格式.样式. ※ 设置jQuery ui的onClose事件,使开始和结束时间 ...

  8. jQuery下拉框扩展和美化插件Chosen

    Chosen 是一个支持jquery的select下拉框美化插件,它能让丑陋的.很长的select选择框变的更好看.更方便.不仅如此,它更扩展了select,增加了自动筛选的功能.它可对列表进行分组, ...

  9. jQuery下拉框插件8种效果

    jQuery自定义漂亮的下拉框插件8种效果 jquery美化选择器实例有:边框.下划线. 伸缩 .滑动. 覆盖. 旋转. 弹出层选择 .环形效果. 在线预览 <body class=" ...

随机推荐

  1. iframe使用

    iframe是一个前端页面的内联框架(即行内框架),使用很方便, <!--嵌套子页面--> <script type="text/x-template" id=& ...

  2. mybatis源码解析3---XMLConfigBuilder解析

    1.XMLConfigBuilder XMLConfigBuilder类位于Mybatis包的org.apache.ibatis.builder.xml目录下,继承于BaseBuilder类,关于Ba ...

  3. Shell 比较两个数的大小

    格式很重要多一个空格少一个空格都可能出错 li@ubuntu:~/test$ cat compare.sh #!/bin/bash read x read y if [ $x -lt $y ] the ...

  4. brctl 命令详解

    安装网桥管理工具包:bridge-utile ```# yum install bridge-utils -y``` ```使用brctl命令创建网桥br1```# brctl addbr br1`` ...

  5. sparkStrming 实时插入 mysql 今天使用echart 实现了简单数据展示 很low 但学习必须加深

  6. makefile 双冒号规则

    双冒号规则就是使用“::”代替普通规则的“:”得到的规则.当同一个文件作为多个规则的目标时,双冒号规则的处理和普通规则的处理过程完全不同(双冒号规则允许在多个规则中为同一个目标指定不同的重建目标的命令 ...

  7. usb帧格式

    源: usb帧格式

  8. js 解密 16进制转10进制,再取ascii码的对应值

    如:\x64 对应 16进制 0x64 转10进制就是 0x64.toString(10) == 100, 查对应的ascii码表得到 ‘d' <div id=code style='displ ...

  9. Golang字符串解析成数字

    package main import ( "strconv" "fmt" ) func main() { // 使用ParseFloat解析浮点数,64是说明 ...

  10. P4381 [IOI2008]Island(基环树+单调队列优化dp)

    P4381 [IOI2008]Island 题意:求图中所有基环树的直径和 我们对每棵基环树分别计算答案. 首先我们先bfs找环(dfs易爆栈) 蓝后我们处理直径 直径不在环上,就在环上某点的子树上 ...