/** * ui-select美化插件 * 基于jquery */ ; + function($) { "use strict"; // 默认实例化配置 var defaults = { width: null, //select的宽度,默认为null将自动获取select的宽度; wrapclass: '', //加载在最外层.ui-select-wrap有class,在自定义样式时有用处; datakey: 'ui-select', //实例化后对象存在select的data键值,方便后续通过data('ui-select')取出; onchange: null, //select值改变时的回调; onclick: null //select元素点击时的回调,diabled时不发生。 }; /** * ui-select插件 */ $.fn.ui_select = function(options) { var _this = $(this), _num = _this.length; // 当要实例的对象只有一个时,直接实例化返回对象; if (_num === 1) { return new ui_select(_this, options); }; // 当要实例的对象有多个时,循环实例化,不返回对象; if (_num > 1) { _this.each(function(index, el) { new ui_select($(el), options); }) } // 当元素个数为0时,不执行实例化。 }; /** * ui_select对象 * @param {[jquery]} el [jquery选择后的对象,此处传入的为单个元素] * @param {[object]} opt [设置的参数] */ function ui_select(el, opt) { this.el = el; this.items = this.el.find('option'); this._opt = $.extend({}, defaults, opt); this._doc = $(document); this._win = $(window); return this._init(); } // ui_select 原型链扩展。 ui_select.prototype = { // 判断是否为ie (6-11); _isie: !!window.activexobject || "activexobject" in window, // init初始化; _init: function() { var _data = this.el.data(this._opt.datakey); // 如果已经实例化了,则直接返回 if (_data) return _data; else this.el.data(this._opt.datakey, this); this._sethtml(); // 组建元素 this._bindevent(); // 绑定事件 }, // 组建并获取相关的dom元素; _sethtml: function() { this.el.addclass('ui-select'); var _ishide = (this.el.css('display') == 'none'); if (_ishide) { this.el.show().css('visibility', 'hidden'); } var _w = this._opt.width ? this._opt.width - 17 : this.el.outerwidth() - 17; this.el.wrap('
') .after('
'); this._wrap = this.el.parent('.ui-select-wrap').css('width', _w); this._input = this.el.next('.ui-select-input'); this._list = this._wrap.children('.ui-select-list'); this.el.prop('disabled') ? this.disable() : null; if (_ishide) { this.el.add(this._wrap).hide(); this.el.css('visibility', null); } var _ohtml = ''; this.el.find('option').each(function(index, el) { var _this = $(el), _text = _this.text(), _value = _this.prop('value'), _selected = _this.prop('selected') ? 'selected' : '', _disabled = _this.prop('disabled') ? ' disabled' : ''; _ohtml += '
  • ' + _text + '
  • '; }); this._list.html(_ohtml); this._items = this._list.children('li'); this.val(this.el.val()); var _txt = this._list.children('li.selected').text(); this._input.text(_txt).attr('title', _txt); }, // 绑定事件; _bindevent: function() { var _this = this; // 模拟后的select点击事件; _this._wrap.on({ // 点击事件 'click': function(e) { // 列表元素点击事件; if (_this._disabled) return; if (e.target.tagname == 'li') { var _self = $(e.target), _val = _self.attr('data-value'); if (_self.hasclass('disabled')) return _this._isie ? e.stoppropagation() : null; _this.val(_val); _this._triggerclick(_val, _this.items.eq(_self.index())); } // ie下点击select时其他select无法收起的bug if (_this._isie) { e.stoppropagation(); _this._allwrap = _this._allwrap || $('.ui-select-wrap'); _this._allwrap.not(_this._wrap).removeclass('focus'); _this._doc.one('click', function() { _this._allwrap.removeclass('focus'); }); } _this._wrap.toggleclass('focus'); _this._setlistcss(); }, // 失去焦点事件 'blur': function(e) { _this._wrap.removeclass('focus'); }, // 键盘事件 'keydown': function(e) { var code = e.keycode; if (code == 40 || code == 38) { var _els = code == 40 ? _this._list.find('li.selected').nextall('li') : _this._list.find('li.selected').prevall('li'); var _val = _els.not('.disabled').eq(0).attr('data-value'); if (_val !== undefined) { _this.val(_val); } return false; } } }); return _this; }, // 根据select所处的位置设置下拉列表显示方向up / down _setlistcss: function() { var _towintop = this._wrap.offset().top - this._win.scrolltop(); var _towinbottom = this._win.height() - _towintop - this._wrap.outerheight(); var _listh = this._list.outerheight(); if (_listh > _towinbottom && _towintop > _towinbottom) { this._wrap.addclass('up'); if (_listh > _towintop) this._list.css('maxheight', _towintop - 1 + 'px'); else this._list.removeattr('style'); } else if (_listh > _towinbottom && _towintop < _towinbottom) { this._wrap.removeclass('up'); this._list.css('maxheight', _towinbottom - 1 + 'px'); } else { this._list.removeattr('style'); this._wrap.removeclass('up'); } }, // change 触发;value:值 ;item:选中的option; _triggerchange: function(value, item) { this.el.change(); this.onchange(value, item); if (typeof this._opt.onchange == 'function') this._opt.onchange.call(this, value, item); }, // click 触发;value:值 ;item:选中的option; _triggerclick: function(value, item) { this.onclick(value, item); if (typeof this._opt.onclick == 'function') this._opt.onclick.call(this, value, item); }, // 获取或设置值; val: function(value) { var _val = this.el.val(); if (value === undefined) return _val; this.el.val(value); var _selectedli = this._list.children('li[data-value="' + value + '"]'); _selectedli.addclass('selected').siblings('li').removeclass('selected'); this._input.html(_selectedli.text()).attr('title', _selectedli.text()); if (_val != value) { return this._triggerchange(value, this.items.eq(_selectedli.index())); } }, // 值改变事件; onchange: function(value, item) {}, // 点击事件; onclick: function(value, item) {}, // 禁用select; disable: function() { this._disabled = true; this.el.prop('disabled', true); this._wrap.addclass('disabled').removeattr('tabindex'); return this; }, // 启用select; enable: function() { this._disabled = false; this.el.prop('disabled', false); this._wrap.removeclass('disabled').attr('tabindex', '0'); return this; }, // 隐藏 hide: function() { this._wrap.hide(); return this; }, // 显示 show: function() { this._wrap.show(); return this; }, // 显示 或 隐藏 toggle: function() { this._wrap.toggle(); return this; }, // visible visible: function(visible) { visible = !visible ? 'hidden' : 'visible'; this._wrap.css('visibility', visible); return this; } }; }(jquery);