浏览 7185 次
锁定老帖子 主题:[原创] 美化select控件最简单的办法
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-06-12
下面的方法是通过JS替换页面内原有的select, 我们希望这个JS是非侵入式的,只要引用了select.js这个js文件的页面,就自动把页面里原有的select控件替换接管了。 先初步地实现selct控件的替换,和基本的交互(暂不考虑接管select的onchange事件等问题)。在下面的实现方法里并没有把原有的select去掉,只是隐藏了起来,所以如果select是在表单内,表单仍然能够正常提交。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <style> body, table, input, textarea, select{ margin: 0; font-size: 12px; line-height:1.5; font-family: Tahoma, SimSun, sans-serif; } .zSelect { display:inline-block; *zoom: 1; *display: inline; position:relative; height:20px; vertical-align:middle; } .zSelect .inputText { line-height: 17px; font-size:12px; background: #f7fafc; padding: 1px 17px 0 1px; border: 1px solid #68a; vertical-align: top; cursor:default; height: 17px; margin:0; } .zSelect .arrowimg { display:inline-block; *zoom: 1; *display: inline; position:relative; cursor:pointer; width:18px; height:20px; left:-18px; margin-right:-18px; vertical-align: top; outline:none; background: url(http://www.wangzhaohui.com/wp-content/uploads/2009/06/arrow.gif); } .zSelect .arrowimg:hover { background: url(http://www.wangzhaohui.com/wp-content/uploads/2009/06/arrow_over.gif); } .optgroup { position:absolute; z-index:666; left:0; top:19px; color: #369; } .optgroup p{ margin:0;} .optgroup div.optionsDiv{ padding:1px; overflow: auto; overflow-x: hidden; max-height:300px; color: #369; border: 1px solid #678; background: #f7fafc; width:auto; z-index:888; filter: Alpha(Opacity=90); opacity: 0.9; } .optgroup a, .optgroup a:visited{ font-size:12px; text-decoration:none; cursor:default; display:block; color: #369; white-space: nowrap; padding:1px 3px 2px 6px; _padding:0 3px 0 6px; height:18px; min-width:2em; } .optgroup a:hover,.optgroup a.selected:hover{ color: #dff; text-decoration:none; background:#38d; } .optgroup a.selected,.optgroup a:focus{ color: #eff; text-decoration:none; background:#49e; } </style> <script> function replaceSelects() { selects = document.getElementsByTagName('select'); for(var i=0; i < selects.length; i++) { var selectWidth=selects.clientWidth; var selectArea = document.createElement('span'); var textInput = document.createElement('input'); var button = document.createElement('a'); selectArea.id = "mySelect"+i; selectArea.className = "zSelect"; textInput.type = "text"; textInput.className = "inputText"; textInput.readOnly=true; textInput.style.width=selectWidth+"px"; textInput.id = "mySelectText"+i; textInput.value = selects.options[0].text; button.className = "arrowimg"; button.href="javascript:showOptions("+i+")"; button.hideFocus=true; selectArea.appendChild(textInput); selectArea.appendChild(button); selects.style.display='none'; selects.parentNode.insertBefore(selectArea, selects); var optgroup = document.createElement('div'); optgroup.className = "optgroup"; optgroup.style.width=selectWidth+20+"px"; optgroup.style.display = "none"; optgroup.id = "optgroup"+i; var optionsDiv = document.createElement('div'); optionsDiv.className = "optionsDiv"; optionsDiv.id = "optionsDiv"+i; optgroup.appendChild(optionsDiv); if(selects.id=="")selects.id="select"+i; selectArea.appendChild(optgroup); for(var j=0; j < selects.options.length; j++) { var optionHolder = document.createElement('p'); var optionLink = document.createElement('a'); var optionTxt = document.createTextNode(selects.options[j].text); optionLink.href = "javascript:showOptions("+i+"); selectMe('"+selects.id+"',"+j+","+i+");"; optionLink.appendChild(optionTxt); optionHolder.appendChild(optionLink); optionsDiv.appendChild(optionHolder); if(selects.options[j].selected){selectMe(selects.id,j,i);} } } } function showOptions(g) { var elem = document.getElementById("optgroup"+g); elem.style.display=elem.style.display=='none'?'block':'none'; } function selectMe(selectFieldId,linkNo,selectNo) { optionLinks = document.getElementById("optionsDiv"+selectNo).getElementsByTagName("a"); for(var k = 0; k < optionLinks.length; k++) { if(k==linkNo) { optionLinks[k].className = "selected"; } else { optionLinks[k].className = ""; } } selectField = document.getElementById(selectFieldId); for(var k = 0; k < selectField.options.length; k++) { if(k==linkNo) { selectField.options[k].selected = "selected"; } else { selectField.options[k].selected = ""; } } var newText = selectField.options[linkNo].text; document.getElementById("mySelectText"+selectNo).value=newText; } window.onload=replaceSelects; </script> <div>当前站点: <select name="select"> <option value="123123">政府门户类演示站</option> <option value="456456">新闻门户类演示站</option> <option value="789789">企业形象类演示站</option> </select> << 当前站点: <select name="select2"> <option value="123123">政府门户类演示站</option> <option value="456456">新闻门户类演示站</option> <option value="789789">企业形象类演示站</option> </select> << </div>OK,在ff3下测试通过,在ie下存在层的定位问题,当弹出下拉列表时需要对层的z-index作调整,在这就不展示了。 如果这个select控件仅在前台作小量的应用,那么适当地添加一些对键盘,鼠标的响应,就差不多可以了。 select控件实现的思考过程和进一步优化请看我的另一个帖子《分享我们的select控件设计过程 》 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-06-12
我也干过这种事情,把原来的textbox 隐藏,加个 select, 然后select 改变后同步 textbox,但是在 asp.net里面做的,要考虑页面回发,麻烦很多。。。
|
|
返回顶楼 | |
发表时间:2010-01-28
看了一遍,实现的很不错,还差点东西:
1.select控件时支持键盘上下键的(↑↓) 2.select控件在弹出后按esc是可以取消的,你这个貌似还没有做到。 说实话,select这个控件很麻烦,不用吧还不行,用吧修改样式太难 |
|
返回顶楼 | |
发表时间:2010-02-16
楼主能不能把select下拉放大一点?就是原来只能显示2个字,然后下拉了显示20个字,这20个字都能看到
|
|
返回顶楼 | |
发表时间:2010-02-16
一般最常用的方法就是不用select而是在input的上包装层,你的方法对于一些希望保留原始的select但是又想改变select外观的情况确实实用。但貌似有一些bug,帮你修复了bug并且在不伤原貌的前提下做了一些细微的优化。
另外这个var selectWidth=selects.clientWidth;就算指的是某个select也没找到是什么浏览器下的属性,恕才疏学浅,改用直接用最长的option的字符长度计算select的宽度。 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <style> body, table, input, textarea, select{ margin: 0; font-size: 12px; line-height:1.5; font-family: Tahoma, SimSun, sans-serif; } .zSelect { display:inline-block; /*zoom: 1; display: inline; */ position:relative; height:20px; vertical-align:middle; } .zSelect .inputText { line-height: 17px; font-size:12px; background: #f7fafc; padding: 1px 17px 0 1px; border: 1px solid #68a; vertical-align: top; cursor:default; height: 17px; margin:0; } .zSelect .arrowimg { display:inline-block; /*zoom: 1; display: inline; */ position:relative; cursor:pointer; width:18px; height:20px; left:-18px; margin-right:-18px; vertical-align: top; outline:none; background: url(http://www.wangzhaohui.com/wp-content/uploads/2009/06/arrow.gif); } .zSelect .arrowimg:hover { background: url(http://www.wangzhaohui.com/wp-content/uploads/2009/06/arrow_over.gif); } .optgroup { position:absolute; z-index:666; left:0; top:19px; color: #369; } .optgroup p{ margin:0; } .optgroup div.optionsDiv{ padding:1px; overflow: auto; overflow-x: hidden; max-height:300px; color: #369; border: 1px solid #678; background: #f7fafc; width:auto; z-index:888; filter: Alpha(Opacity=90); opacity: 0.9; } .optgroup a { font-size:12px; text-decoration:none; cursor:default; display:block; color: #369; white-space: nowrap; padding:1px 3px 2px 6px; /*padding:0 3px 0 6px; */ height:18px; min-width:2em; } .optgroup a:hover { color: #dff; text-decoration:none; background:#38d; } div.optgroup a.selected{ color: #eff; text-decoration:none; background:#49e; } </style> <script> function replaceSelects() { var selects = document.getElementsByTagName('select'); for(var i = 0, sLen = selects.length; i < sLen; i++) { var selectWidth = 200; var maxLen = 0; var sel = selects[i]; sel.style.display='none'; //隐藏原始列表 if(!sel.id) sel.id="select"+i; var selId = sel.id; var defaultSelect = -1; //新建列表区域 var fragment = document.createDocumentFragment(); var selectArea = document.createElement('span'); var textInput = document.createElement('input'); selectArea.id = "select_"+selId; selectArea.className = "zSelect"; textInput.type = "text"; textInput.className = "inputText"; textInput.readOnly=true; textInput.id = "input_"+selId; textInput.value = ''; var button = document.createElement('a'); button.id = "arrow_"+selId; button.className = "arrowimg"; button.href='javascript:showOptions("optgroup_'+selId+'");'; selectArea.appendChild(textInput); selectArea.appendChild(button); //新建列表菜单 var optgroup = document.createElement('div'); optgroup.className = "optgroup"; optgroup.style.display = "none"; optgroup.id = "optgroup_" + selId; var optionsDiv = document.createElement('div'); optionsDiv.className = "optionsDiv"; optionsDiv.id = "optionsDiv_"+selId; optgroup.appendChild(optionsDiv); //添加菜单项 for(var j = 0, soLen = sel.options.length; j < soLen; j++) { var option = sel.options[j]; var text = option.text; if(text.length > maxLen){ maxLen = text.length; } var optionLink = document.createElement('a'); optionLink.href = 'javascript:showOptions("'+optgroup.id+'"); selectMe("'+sel.id+'","'+j+'");'; var optionTxt = document.createTextNode(text); optionLink.appendChild(optionTxt); optionsDiv.appendChild(optionLink); if(option.selected) defaultSelect = j; } selectWidth = maxLen * 12 + 10; textInput.style.width = selectWidth+"px"; optgroup.style.width = selectWidth + 20 + "px"; selectArea.appendChild(optgroup); fragment.appendChild(selectArea); sel.parentNode.insertBefore(fragment, sel); //保持默认选项 if(defaultSelect != -1){ selectMe(sel.id,defaultSelect); } } }; function showOptions(optgroupId) { var optgroup = document.getElementById(optgroupId); optgroup.style.display = optgroup.style.display === 'none' ? 'block' : 'none'; }; function selectMe(selectId, linkNo) { var selectField = document.getElementById(selectId); var optionLinks = document.getElementById("optionsDiv_"+selectId).getElementsByTagName("a"); var newText; for(var k = 0, oLen = optionLinks.length; k < oLen; k++) { var option = selectField.options[k]; if(k==linkNo) { optionLinks[k].className = "selected"; option.selected = "selected"; newText = option.text; } else { optionLinks[k].className = ""; option.selected = ""; } } document.getElementById("input_"+selectId).value=newText; } window.onload=replaceSelects; </script> </head> <body> <div>当前站点1: <select id="select1"> <option value="123123">政府站</option> <option value="456456">新闻类演示站</option> <option value="789789">企业形象类演示站</option> </select> 当前站点2: <select id="select2"> <option value="123123">政府类</option> <option value="456456">新闻门户</option> <option value="789789">企业形象类</option> </select> </div> </body> </html> |
|
返回顶楼 | |