jQuery自定义多选下拉框
项目中需要自定义一个下拉框多选插件,业务问题还是自己实现比较好
通过$.fn 向jQuery添加新的方法
下拉数据通过参数传递进去,通过调用该插件时接收,选择后的确定与取消事件采用事件传递方式
代码如下:
1.效果图
2.代码
1 <div id="demo" class="dropdown-container"> 2 <div class="dropdown-display"> 3 <span></span> 4 <input type="text" class="iptdiplay" placeholder="请选择" readonly="readonly" /> 5 </div> 6 <div class="dropdown-panel"> 7 <div class="dropdown-search"> 8 <span></span> 9 <input type="text" class="iptsearch" placeholder="关键字搜索" /> 10 </div> 11 <ul class="dd-select"> 12 <!-- area for dropdown items --> 13 </ul> 14 <div class="dropdown-opt"> 15 <button class="dd-btn ok">确定</button> 16 <button class="dd-btn cancel">取消</button> 17 </div> 18 </div> 19 </div>
1 .dropdown-container{ 2 display: block; 3 width: 200px; 4 height: 30px; 5 padding: 0px; 6 position: relative; 7 margin: 0px auto; 8 } 9 10 .dropdown-display{ 11 display: block; 12 height: 30px; 13 position: absolute; 14 top: 0; 15 width:100%; 16 margin: 0px; 17 border:1px solid steelblue; 18 } 19 .dropdown-display span{ 20 background: url(../static/choose_down_icon_01.png) no-repeat left 8px; 21 display: block; 22 height: 25px; 23 width: 10px; 24 position: absolute; 25 right: 5px; 26 top: 3px; 27 } 28 .dropdown-display input[class='iptdiplay']{ 29 border: none; 30 border-color: transparent; 31 background: transparent; 32 border-radius: 0px; 33 box-shadow: none; 34 height: 30px; 35 width: 100%; 36 margin: 0px; 37 box-sizing: border-box; 38 box-shadow: none; 39 padding-left: 10px; 40 padding-right: 18px; 41 outline: none; 42 cursor: pointer; 43 text-overflow: ellipsis; 44 } 45 .dropdown-panel { 46 position: absolute; 47 top: 32px; 48 width:100%; 49 padding: 0px; 50 display: none; 51 border-left: 1px solid steelblue; 52 border-bottom: 1px solid steelblue; 53 border-right: 1px solid steelblue; 54 } 55 56 .dropdown-panel .dropdown-search{ 57 display: block; 58 width: 100%; 59 height: 30px; 60 } 61 .dropdown-search span{ 62 background: url(../static/chosen-sprite.png) no-repeat 100% -20px,linear-gradient(#eee 1%,#fff 15%); 63 display: block; 64 height: 25px; 65 width: 20px; 66 position: absolute; 67 right: 0px; 68 top: 3px; 69 } 70 .dropdown-search input[class='iptsearch']{ 71 border: none; 72 border-color: transparent; 73 background: transparent; 74 border-radius: 0px; 75 box-shadow: none; 76 height: 30px; 77 width: 100%; 78 margin: 0px; 79 box-sizing: border-box; 80 box-shadow: none; 81 padding-left: 10px; 82 outline: none; 83 } 84 .dropdown-panel .dd-select{ 85 display: block; 86 width:100%; 87 position: relative; 88 height: auto; 89 margin: 0px; 90 padding:0px !important; 91 box-sizing: border-box; 92 list-style-type: none; 93 text-align: left; 94 max-height: 300px; 95 overflow-y: scroll; 96 overflow-x: hidden; 97 } 98 .dd-item{ 99 display: block; 100 height: 30px; 101 line-height: 30px; 102 padding-left: 5px; 103 border-bottom: 1px solid steelblue; 104 font-size: 13px; 105 z-index: 8; 106 overflow: hidden; 107 } 108 .dd-item .dd-v{ 109 width: 0px; 110 height: 0px; 111 display: none; 112 } 113 .dd-item .dd-k{ 114 z-index: 8; 115 padding-left: 15px; 116 } 117 .dd-item:first-child{ 118 border-top: 1px solid steelblue; 119 } 120 .dd-item:last-child{ 121 border-bottom: none; 122 } 123 .dd-select .on{ 124 background-color: steelblue\9; 125 } 126 .dd-item:hover::before,.dd-item:hover before{ 127 content:'\2714'; 128 position: absolute; 129 left: 0px; 130 color: #79a979 131 z-index: 9; 132 font-size: 16px; 133 padding-right: 3px; 134 padding-left: 2px; 135 background-color: #fff; 136 } 137 .dd-select .on::before,.dd-select .on before{ 138 content:'\2714'; 139 position: absolute; 140 left: 0px; 141 color: green; 142 z-index: 9; 143 font-size: 16px; 144 padding-right: 3px; 145 padding-left: 2px; 146 background-color: #fff; 147 } 148 .dd-item:hover{ 149 cursor: pointer; 150 background-color: #ccc; 151 } 152 .dropdown-container .dropdown-opt{ 153 width:100%; 154 text-align: center; 155 position: absolute; 156 left: -1px; 157 bottom: -30px; 158 padding: 0px; 159 border-left: 1px solid steelblue; 160 border-bottom: 1px solid steelblue; 161 border-right: 1px solid steelblue; 162 box-sizing: content-box; 163 } 164 .dropdown-container .dd-btn{ 165 color: #333; 166 height: 28px !important; 167 display: inline-block; 168 background-color: #e6e6e6; 169 border-color: #adadad; 170 user-select: none; 171 background-image: none; 172 border: 1px solid transparent; 173 border-radius: 4px; 174 margin: 0px 15px; 175 } 176 .dropdown-container .dd-btn:hover{ 177 color:#fff; 178 background-color: steelblue; 179 } 180 /* scrollbar */ 181 .dropdown-container ::-webkit-scrollbar { width: 5px; height: 10px; } 182 .dropdown-container ::-webkit-scrollbar-track, 183 .dropdown-container ::-webkit-scrollbar-thumb { border-radius: 999px; border: 5px solid transparent; } 184 .dropdown-container ::-webkit-scrollbar-track { box-shadow: 1px 1px 5px rgba(0,0,0,.2) inset; } 185 .dropdown-container ::-webkit-scrollbar-thumb { min-height: 20px; background-clip: content-box; box-shadow: 0 0 0 5px rgba(0,0,0,.2) inset; } 186 .dropdown-container ::-webkit-scrollbar-corner { background: transparent; }
3.Jquery插件
;(function ($,window,document,undefined) { var _pluginName="jqDropdown"; var defaults = { items:[] }; var parm=[]; //es5 filter hack if (!Array.prototype.filter){ Array.prototype.filter = function(fun){ var len = this.length; if (typeof fun != "function") throw new TypeError(); var res = new Array(); var _arg = arguments[1]; for (var i = 0; i < len; i++){ if (i in this){ var val = this[i]; if (fun.call(_arg, val, i, this)) res.push(val); } } return res; }; } if(!Array.prototype.indexOf) { Array.prototype.indexOf = function (elem, startFrom) { var startFrom = startFrom || 0; if (startFrom > this.length) return -1; for (var i = 0; i < this.length; i++) { if (this[i] == elem && startFrom <= i) { return i; } else if (this[i] == elem && startFrom > i) { return -1; } } return -1; } } var init = function (o,opts,okFn,cancelFn) { var _panel=$(o); var _ul=_panel.find(".dd-select:eq(0)"); function createDropItems(items,p){ p=p||[]; _ul.empty(); var _curretVal=$(".iptdiplay").val(); for(var i=0,len=items.length;i<len;i++){ var _d=items[i]; var _li='<li class="{{DC}}"> <span class="dd-v">{{DV}}</span><span class="dd-k">{{DK}}</span></li>'; _ul.append(_li.replace(/{{DV}}/g, _d.val).replace(/{{DK}}/g,_d.name).replace(/{{DC}}/g,p.indexOf(_d.val.toString())>-1?'dd-item on':'dd-item')); } _panel.find('.dd-item').click(function(e){ var $this=$(this); var _k_= $this.find('.dd-k:eq(0)').text() var _v_= $this.find('.dd-v:eq(0)').text(); if($this.hasClass('on')){ parm=parm.filter(function(t){ return t!=_v_; }); $this.removeClass('on'); }else{ parm.push(_v_); $this.addClass('on'); } var disArr=[]; for(var i=0,len=items.length;i<len;i++){ var _d=items[i]; if(parm.indexOf(_d.val.toString())>-1) disArr.push(_d.name); } $(".iptdiplay").val(disArr.join('|')); }); }; //init to build dropdown items createDropItems(opts.items||[]); function toggleDrop(){ $(".dropdown-panel").slideToggle(); }; //search $(".iptsearch").bind("input propertychange",function(e){ if(!e) return; var _sk=e.currentTarget.value; var _items=opts.items||[]; createDropItems(_items.filter(function(d){ return d.name.indexOf(_sk)>-1; }),parm); }); //Toggle dropdown $(".dropdown-display").click(function(){ toggleDrop(); }); //OK button event $(".dropdown-opt button.ok").click(function(){ toggleDrop(); okFn&&okFn.apply(this,[parm]); }); //Cancel button event $(".dropdown-opt button.cancel").click(function(){ toggleDrop(); cancelFn&&cancelFn.call(this); }); }; $.fn[_pluginName] = function (options,okFn,cancelFn) { var options = $.extend(defaults, options); return this.each(function () { init(this,options,okFn,cancelFn); }); } })(jQuery,window,document);
4.页面调用示例
<script> var data=[ { name:'http://58.100.3.12',val:1 }, { name:'http://44.168.4.13',val:2 }, { name:'http://192.168.2.1/sdfsf/234234/234/2/34/23',val:3 }, { name:'http://220.199.5.14',val:4 }, { name:'http://127.1.62.15',val:5 }, { name:'http://127.1.62.15',val:6 }, { name:'http://127.1.62.15',val:7 }, { name:'http://127.1.62.15',val:8 }, { name:'http://127.1.62.15',val:9 }, { name:'http://127.1.62.15',val:10 }, { name:'http://127.1.62.15',val:11 }, { name:'http://127.1.62.15',val:12 }, { name:'http://127.1.62.15',val:13 }, { name:'http://127.1.62.15',val:14}, { name:'http://127.1.62.15',val:15 }, { name:'http://127.1.62.15',val:16 }, { name:'http://127.1.62.15',val:17 }, { name:'http://127.1.62.15',val:18 }, { name:'http://127.1.62.15',val:19 }, { name:'http://127.1.62.15',val:20 }, { name:'http://127.1.62.15',val:21 }, { name:'http://127.1.62.15',val:22 }, { name:'http://127.1.62.15',val:23 }, { name:'http://127.1.62.15',val:24 }, { name:'http://127.1.62.15',val:25 }, { name:'http://127.1.62.15',val:26 }, { name:'http://127.1.62.15',val:27 }, { name:'http://127.1.62.15',val:28 }, { name:'http://127.1.62.15',val:29 } ]; $("#demo").jqDropdown({ items:data },function(e){ console.dir(e); },function(){ console.log('canceled by user !'); }); </script>
5.输出
6.不足
页面样式在不支持css3浏览器中显示有问题 后期需要改进
下拉数据为一次性渲染 如有需要 可设置滚动加载
下拉框滚动条的美化未兼容所有浏览器
搜索时检索数据直接源自页面数据 所有需要添加延迟处理 获取服务端数据
【原创】