带搜索框的jQuery下拉框插件
来源:互联网 发布:apache linux 下载 编辑:程序博客网 时间:2024/05/21 10:48
由于下拉框的条数有几十个,于是打算找一个可以搜索查找功能的下拉框,刚开始在网上看了几个,都是有浏览器兼容性问题,后来看到这个“带搜索框的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层级 },
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 QinE-mail: david@hereapp.cnDate: 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下拉框美化插件searchableSelect
- 带搜索框的jQuery下拉框插件
- jquery实现带搜索的下拉框
- 自定义带搜索框的下拉列表插件
- 使用Jquery实现带搜索框的下拉框
- 带搜索的下拉框
- jQuery的下拉框搜索select2插件用法
- 下拉框带搜索
- 带搜索功能的下拉框select
- 带搜索框选择的下拉列表
- 带搜索功能的下拉框
- jQuery插件 - 漂亮带图标下拉框Javascript image dropdown
- jquery 插件应用 下拉框中带有搜索框
- 可搜索下拉框 模糊查询下拉框 jQuery-searchableSelect插件
- jquery 下拉框搜索控件
- jQuery-searchableSelect(下拉搜索框)
- google 搜索提示 搜索下拉框 jquery
- js实现带搜索功能的下拉框
- 10.27~10.28 NOIP(伪)模拟总结
- Git下的冲突解决
- ESP8266学习笔记——(1)
- REST vs RPC
- 自然语言处理-搭建文本分类器
- 带搜索框的jQuery下拉框插件
- poj 网络流专题
- Dao层与连接池
- ACM数论模版
- vue2.0 点击跳转传参--vue路由跳转传参数
- OGNL
- 【设计模式】(3)--最常用设计模式之适配器模式
- mysql 查询当前时间
- 前端面试题-滴滴一面