项目中需要自定义一个下拉框多选插件,业务问题还是自己实现比较好
通过 $.fn 向 jQuery 添加新的方法
下拉数据通过参数传递进去,通过调用该插件时接收,选择后的确定与取消事件采用事件传递方式
代码如下:
1. 效果图
2. 代码
- <div id="demo" class="dropdown-container">
- <div class="dropdown-display">
- <span>
- </span>
- <input type="text" class="iptdiplay" placeholder="请选择" readonly="readonly"
- />
- </div>
- <div class="dropdown-panel">
- <div class="dropdown-search">
- <span>
- </span>
- <input type="text" class="iptsearch" placeholder="关键字搜索" />
- </div>
- <ul class="dd-select">
- <!-- area for dropdown items -->
- </ul>
- <div class="dropdown-opt">
- <button class="dd-btn ok">
- 确定
- </button>
- <button class="dd-btn cancel">
- 取消
- </button>
- </div>
- </div>
- </div>
- .dropdown - container {
- display: block;
- width: 200px;
- height: 30px;
- padding: 0px;
- position: relative;
- margin: 0px auto;
- }
- .dropdown - display {
- display: block;
- height: 30px;
- position: absolute;
- top: 0;
- width: 100 % ;
- margin: 0px;
- border: 1px solid steelblue;
- }.dropdown - display span {
- background: url(.. / static / choose_down_icon_01.png) no - repeat left 8px;
- display: block;
- height: 25px;
- width: 10px;
- position: absolute;
- right: 5px;
- top: 3px;
- }.dropdown - display input[class = 'iptdiplay'] {
- border: none;
- border - color: transparent;
- background: transparent;
- border - radius: 0px;
- box - shadow: none;
- height: 30px;
- width: 100 % ;
- margin: 0px;
- box - sizing: border - box;
- box - shadow: none;
- padding - left: 10px;
- padding - right: 18px;
- outline: none;
- cursor: pointer;
- text - overflow: ellipsis;
- }.dropdown - panel {
- position: absolute;
- top: 32px;
- width: 100 % ;
- padding: 0px;
- display: none;
- border - left: 1px solid steelblue;
- border - bottom: 1px solid steelblue;
- border - right: 1px solid steelblue;
- }
- .dropdown - panel.dropdown - search {
- display: block;
- width: 100 % ;
- height: 30px;
- }.dropdown - search span {
- background: url(.. / static / chosen - sprite.png) no - repeat 100 % -20px,
- linear - gradient(#eee 1 % , #fff 15 % );
- display: block;
- height: 25px;
- width: 20px;
- position: absolute;
- right: 0px;
- top: 3px;
- }.dropdown - search input[class = 'iptsearch'] {
- border: none;
- border - color: transparent;
- background: transparent;
- border - radius: 0px;
- box - shadow: none;
- height: 30px;
- width: 100 % ;
- margin: 0px;
- box - sizing: border - box;
- box - shadow: none;
- padding - left: 10px;
- outline: none;
- }.dropdown - panel.dd - select {
- display: block;
- width: 100 % ;
- position: relative;
- height: auto;
- margin: 0px;
- padding: 0px ! important;
- box - sizing: border - box;
- list - style - type: none;
- text - align: left;
- max - height: 300px;
- overflow - y: scroll;
- overflow - x: hidden;
- }.dd - item {
- display: block;
- height: 30px;
- line - height: 30px;
- padding - left: 5px;
- border - bottom: 1px solid steelblue;
- font - size: 13px;
- z - index: 8;
- overflow: hidden;
- }.dd - item.dd - v {
- width: 0px;
- height: 0px;
- display: none;
- }.dd - item.dd - k {
- z - index: 8;
- padding - left: 15px;
- }.dd - item: first - child {
- border - top: 1px solid steelblue;
- }.dd - item: last - child {
- border - bottom: none;
- }.dd - select.on {
- background - color: steelblue\9;
- }.dd - item: hover: :before,
- .dd - item: hover before {
- content: '\2714';
- position: absolute;
- left: 0px;
- color: #79a979 z - index: 9;
- font - size: 16px;
- padding - right: 3px;
- padding - left: 2px;
- background - color: #fff;
- }.dd - select.on: :before,
- .dd - select.on before {
- content: '\2714';
- position: absolute;
- left: 0px;
- color: green;
- z - index: 9;
- font - size: 16px;
- padding - right: 3px;
- padding - left: 2px;
- background - color: #fff;
- }.dd - item: hover {
- cursor: pointer;
- background - color: #ccc;
- }.dropdown - container.dropdown - opt {
- width: 100 % ;
- text - align: center;
- position: absolute;
- left: -1px;
- bottom: -30px;
- padding: 0px;
- border - left: 1px solid steelblue;
- border - bottom: 1px solid steelblue;
- border - right: 1px solid steelblue;
- box - sizing: content - box;
- }.dropdown - container.dd - btn {
- color: #333;
- height: 28px ! important;
- display: inline - block;
- background - color: #e6e6e6;
- border - color: #adadad;
- user - select: none;
- background - image: none;
- border: 1px solid transparent;
- border - radius: 4px;
- margin: 0px 15px;
- }.dropdown - container.dd - btn: hover {
- color: #fff;
- background - color: steelblue;
- }
- /* scrollbar */
- .dropdown - container: :-webkit - scrollbar {
- width: 5px;
- height: 10px;
- }.dropdown - container: :-webkit - scrollbar - track,
- .dropdown - container: :-webkit - scrollbar - thumb {
- border - radius: 999px;
- border: 5px solid transparent;
- }.dropdown - container: :-webkit - scrollbar - track {
- box - shadow: 1px 1px 5px rgba(0, 0, 0, .2) inset;
- }.dropdown - container: :-webkit - scrollbar - thumb {
- min - height: 20px;
- background - clip: content - box;
- box - shadow: 0 0 0 5px rgba(0, 0, 0, .2) inset;
- }.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 浏览器中显示有问题 后期需要改进
下拉数据为一次性渲染 如有需要 可设置滚动加载
下拉框滚动条的美化未兼容所有浏览器
搜索时检索数据直接源自页面数据 所有需要添加延迟处理 获取服务端数据
来源: http://www.jb51.net/article/116531.htm