高仿select
最近也不知道在瞎忙些什么,七月份一篇日志没写。昨天公司项目要求模拟一个select。其实这玩意以前也写过。只是感觉没做好。所以又重写了一个。和系统默认的很相近吧。说明一下吧:
一:鼠标点击这个肯定不用说了
二:支持键盘上下键,回车键选择
三:用tab键获得焦点后。也支持键盘上下键选择,无须弹出下拉菜单。
其实也没啥,无非就是个select而已。由于这个是用在我们公司项目上的。所以如果你想拿去用,估计有些东西不需要。比如那个回调函数,或者参数。这个你自己改一下就可以了。可以将回调函数作为一个属性放到opts里。
调用方式:newsky_select('mySelect1',function(){},{oClass:'aa',width:250}),如果你不想写回调函数,可以省掉,不过得改下js,将init:function(obj,callback,opts)里面callback和opts换下位置就可以了。opts里只定了width和class两个属性,width是模拟后的select的宽度。class就是模拟后的select的类了。废话不多说了。上代码:
function sky_select() { this.init.apply(this, arguments) }; sky_select.prototype = { init: function(obj, callback, opts) { var _this = this, o = this.getObj(obj), temp = []; opts = opts || {}; this.oOptions = o.options; this.current = 0; this.n = 0; sky_oIndex = 100; this.callback = callback; this.stopEnter = true; this.box = document.createElement('div'); this.oInput = document.createElement('input'); this.oItmes = document.createElement('ul'); var width = opts.width || o.offsetWidth this.box.style.width = width + 'px'; this.oInput.style.width = width - 7 + 'px'; this.box.className = opts.oClass || 'select_wrap'; this.oInput.setAttribute('type', 'text'); this.oInput.setAttribute('readonly', 'readonly'); this.oInput.className = 'likeSelect'; var index = o.options.selectedIndex; this.oInput.value = this.oOptions[index || 0].value; if (index) this.current = index; for (var i = 0, len = this.oOptions.length; i < len; i++) { temp.push(this.oOptions[i].value) }; this.oItmes.innerHTML = '<li>' + temp.join('</li><li>') + '</li>'; this.box.appendChild(this.oInput); this.box.appendChild(this.oItmes); o.parentNode.appendChild(this.box); o.style.display = 'none'; this.item = this.oItmes.getElementsByTagName('li'); this.oItmes.style.display = 'none'; this.oInput.onclick = function() { _this.show() }; this.oInput.onfocus = function() {}; this.oInput.onblur = function() { this.stopEnter = true; }; this.toSelect(this.item); this.hide(); }, getObj: function(el) { return el = typeof el == 'string' ? document.getElementById(el) : el; }, show: function() { var style = this.oItmes.style.display || 'none'; this.oItmes.style.display = style == 'none' ? 'block': 'none'; if (style == 'none') this.keyEvent(); this.item[this.current].className = 'active'; this.n = this.current; }, toSelect: function(obj) { var _this = this; for (var i = 0, len = obj.length; i < len; i++) { (function(i) { obj[i].onclick = function() { _this.oInput.value = this.innerHTML; _this.oOptions[i].selected = true; _this.n = _this.current = i; _this.oItmes.style.display = 'none'; _this.box.style.position = 'static'; if (_this.callback && typeof _this.callback == 'function') _this.callback(); }; obj[i].onmouseover = function() { _this.item[_this.current].className = ''; this.className = 'active'; _this.n = i; } obj[i].onmouseout = function() { this.className = ''; } })(i); }; }, keyEvent: function() { var _this = this; var style = this.oItmes.style.display || 'none'; if (style == 'none') return; this.stopEnter = false; this.box.parentNode.style.zIndex = sky_oIndex++; this.oItmes.onmouseout = function() { _this.item[_this.current].className = 'active'; }; document.onkeyup = function(e) { e = e || window.event; switch (e.keyCode) { case 38: _this.up(); break; case 40: _this.down(); break; case 13: _this.enter(); break; default: ; } } }, up: function() { if (this.n == 0) return; this.n--; this.item[this.current].className = ''; this.current = this.n; this.item[this.n].className = 'active'; this.oInput.value = this.item[this.n].innerHTML; this.oOptions[this.n].selected = true; }, down: function() { if (this.n == this.item.length - 1) return; this.n++; this.item[this.current].className = ''; this.current = this.n; this.item[this.n].className = 'active'; this.oInput.value = this.item[this.n].innerHTML; this.oOptions[this.n].selected = true; }, enter: function() { if (this.stopEnter) return; this.oInput.value = this.item[this.n].innerHTML; this.oOptions[this.n].selected = true; this.current = this.n; this.oItmes.style.display = 'none'; if (this.callback && typeof this.callback == 'function') this.callback(); this.stopEnter = true; }, hide: function() { var _this = this; this.addEvent(document, 'click', function(e) { e = e || window.event; var targ = e.target || e.srcElement; if (targ != _this.oItmes && targ != _this.oInput) _this.oItmes.style.display = 'none'; }) }, addEvent: function(elm, evType, fn, useCapture) { if (elm.addEventListener) { elm.addEventListener(evType, fn, useCapture); return true; } else if (elm.attachEvent) { var r = elm.attachEvent('on' + evType, fn); return r; } else { elm['on' + evType] = fn; } } }
HTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题文档</title> <style type="text/css"> * { margin:0; padding:0; font-family:Arial, Helvetica, sans-serif; font-size:11px; } ul { list-style:none; } .box { margin:10px auto; width:250px; height:24px; position:relative; } .aa { position:absolute; top:0; left:0; } .likeSelect { display:block; height:22px; line-height:22px; background:url(images/icon_select_arrow.gif) no-repeat 100% 8px; border:1px solid; border-color:#aeaeae #e5e5e5 #e5e5e5; padding-left:5px; cursor:default; } div ul { border:1px solid #e5e5e5; padding:1px; margin-top:-1px; *margin-top:-2px; background:#fff; } div ul li { height:20px; line-height:20px; text-decoration:none; color:#000; display:block; padding-left:5px; cursor:default; } div ul li.active { background:#B91F33; color:#fff; } </style> <script type="text/javascript" src="myselect.js"></script> <script type="text/javascript"> window.onload = function(){ var myselect = document.getElementById('mySelect') new sky_select('mySelect',function(){alert(myselect.options[myselect.options.selectedIndex].value)},{oClass:'aa',width:250}) new sky_select('mySelect1',function(){},{oClass:'aa',width:250}) } </script> </head> <body> <div class="box"> <select name="" id="mySelect"> <option value="default">default</option> <option value="options1">options1</option> <option value="options2">options2</option> <option value="options3" selected="selected">options3</option> <option value="options4">options4</option> <option value="options5">options5</option> </select> </div> <div class="box"> <select name="" id="mySelect1"> <option value="default">default</option> <option value="options1">options1</option> <option value="options2">options2</option> <option value="options3">options3</option> <option value="options4">options4</option> <option value="options5">options5</option> </select> </div> </body> </html>
另:右边那个小三角自己做一个吧。