基于jQuery的模仿下拉框的插件
由于项目的需要,做了一个模仿下拉框的jQuery插件。原生的select有点丑,功能比较单一。
目前的版本只提供多选式操作。后续会接着完善。我测试了大多的浏览器,目前都兼容。现分享出来大家一块进步。
如图所示:
选中后的效果:
目前支持的功能有:
1. 选中的数据进行靠前排序
2. 下拉框可使用键盘键ESC关闭
3. 支持键盘的上下键切换数据(回车即可选中数据)
4. 支持输入检索数据
5. 大多浏览器都兼容
下面就把代码贴上来。
HTML部分:
View Code
<!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>javascript</title> <script type="text/javascript" src="js/jquery-1.8.3.js"></script> <script type="text/javascript" src="js/jquery.select.js"></script> <style type="text/css"> body { font-size:12px; padding:0; margin:0;} #main { width:500px; padding:20px 0 0 10px;} .searchSelect{ background:url(images/select.jpg) no-repeat; width:142px; height:21px; line-height:21px; border:none; padding:0 18px 0 0px; text-align:center; } .searchSelect input{ border:none; width:134px; height:21px; line-height:21px; background:none; } .searchSelect-UL, .checkSelect-UL { background:#FFF; position:absolute; border:#999 1px solid; overflow-y:auto; overflow-x:hidden; z-index:999999; display:none; } .searchSelect-UL li { display:block; height:24px; line-height:24px; padding:0 8px; cursor:pointer; color:#888; overflow:hidden; vertical-align:middle; word-wrap:break-word; word-break:break-all; } .searchSelect-UL li:hover { background:#E8E8E8; } .searchSelect-UL li.cur { background:#E8E8E8; color:#333; font-weight:bold; } .searchSelect-UL span { height:24px; line-height:24px; padding:0px 4px; color:#FFF; font-weight:bold; background:#559FE2; display:block; overflow:hidden; } /*复选框样式*/ .checkSelect-UL ul { margin:0; padding:0; list-style:none; } .checkSelect-UL li{ display:block; height:25px; line-height:25px; padding:0 8px 0 26px; cursor:pointer; color:#888; overflow:hidden; word-wrap:break-word; word-break:break-all; background-image:url(images/checkbox_no.png); background-repeat:no-repeat; background-position:4px 2px; } .checkSelect-UL li:hover, .checkSelect-UL li.sel{ background:#E8E8E8; background-image:url(images/checkbox_no.png); background-repeat:no-repeat; background-position:4px 2px; } .checkSelect-UL li.cur{ background:#E8E8E8; color:#000; background-image:url(images/checkbox_yes.png); background-repeat:no-repeat; background-position:4px 2px; } </style> </head> <body> <div id="main"> <div class="searchSelect"> <input type="text" id="userSelect" name="userText" /> </div> </div> <script type="text/javascript"> $(document).ready(function(){ var defaultUser = "", userData = [["2", "张三", "zhangsan"], ["3", "李四", "lisi"], ["4", "王五", "wangwu"], ["5", "赵六", "zhaoliu"], ["6", "孙七", "sunqi"], ["7", "周八", "zhouba"], ["8", "吴九", "wujiu"], ["9", "郑十", "zhengshi"]]; $("#userSelect").searchSelect({ data: userData, defaultVal: defaultUser, maxHeight: 140 }); }); </script> </body> </html>
js部分:
View Code
;(function(jQuery, undefined) { $.fn.searchSelect = function(options) { var thisObj = this, id = thisObj.attr("id"), objId = "checkSelect-UL-" + id, title_arr = [], firstArr = [], nextArr = [], tempObj = {}, moveNum = -1, defaults = { data: [], //数据 maxWidth: 158, maxHeight: 240, liHeight: 25, //定义LI的高度,默认25px defaultText: "请选择...", defaultVal: "", onChange: function(val){} }, options = $.extend(defaults, options), value_arr = (options.defaultVal.indexOf(",") > -1 ? options.defaultVal.split(",") : options.defaultVal) || []; //赋值 thisObj.val(options.defaultVal || options.defaultText); if (options.defaultVal != "") { init(); var textInput = options.defaultText; if(title_arr.length > 0) textInput = title_arr.join(","); $("#" + id).val(textInput); } thisObj.click(function() { thisObj.val(""); //滚动条回到顶部 $("#" + objId).scrollTop = 0; //读取LI列表 getCheckDataList(); //定位 getPosition(objId, thisObj); //为LI添加点击事件 listSlideDown(); var eventFunc = attachEvent(); eventFunc(document, 'mousedown', function (event) { if (!event) event = window.event; var el = $(event.srcElement || event.target); if (el[0].id != objId && el.parents('#' + objId).length == 0 && el[0] != $("#" + id).get(0)) { closeCheckSelect(); } }, false); }); //键盘事件 thisObj.keyup(function(e) { switch (e.keyCode) { case 27: //ESC closeCheckSelect(); break; case 13: //ENTER case 38: //UP case 40: //DOWN upDownKey(e.keyCode); break; default: if (thisObj.val() != "") { options.onChange(thisObj.val()); } getCheckDataList(); break; } }); function init() { $.each(value_arr, function(i, item) { $.each(options.data, function(j, val) { var itemString = val.join(""); if (item == val[0]) { title_arr.push(val[1]); firstArr.push(val); } else if (!tempObj[itemString] && $.inArray(val[0], value_arr) == -1) { nextArr.push(val); tempObj[itemString] = true; } }); }); //选中的排到最顶部 options.data = firstArr.concat(nextArr); } function attachEvent() { if (window.addEventListener) { return function(el, eventName, fn, capture) { el.addEventListener(eventName, fn, (capture)); }; } else if(window.attachEvent) { return function(el, eventName, fn, capture) { el.attachEvent("on" + eventName, fn); }; } else { return function() {}; } } function listSlideDown() { var isShow = arguments[0] || ""; $("#" + objId + " li").unbind().bind("click", function(){ var thisVal = $(this).attr('value'); if ($(this).hasClass("cur")) { $(this).removeClass("cur"); if ($.inArray(thisVal + "", value_arr) != -1) { unsetArray(thisVal, value_arr); unsetArray($(this).text(), title_arr); } } else { $(this).addClass("cur"); if ($.inArray(thisVal + "", value_arr) == -1) { value_arr.push(thisVal + ""); title_arr.push($(this).text()); } } $("#checkSelect-hidden-" + id).val(value_arr.join(",")); }); (isShow == "") && $("#" + objId).slideDown(500); } //关闭层 function closeCheckSelect() { listSlideDown("close"); $("#" + objId).slideUp(0); thisObj.val(title_arr.length > 0 ? title_arr.join(",") : options.defaultText); moveNum = -1; } function getPosition(id, obj) { var pos = obj.offset(), isIE6 = ($.browser.msie && $.browser.version < 7), left = !isIE6 ? pos.left - 4 : pos.left - 3, top = !isIE6 ? pos.top + obj.height() + 1 : pos.top + obj.height() + 4; $("#" + objId + " li").css({"height": options.liHeight + "px", "line-height": options.liHeight + "px"}); $("#" + id).css({"overflow-y":"auto", "left": left + "px", "top": top + "px", "width": options.maxWidth + "px", "height": options.maxHeight + "px"}); } //checkbox列表信息 function getCheckDataList() { if (!$.isArray(options.data)) return; var h, dataInfo = preStr = nextStr = "", searchText = thisObj.val(); $.each(options.data, function(i, val) { if ($.inArray(val[0], value_arr) != -1) { preStr += '<li title="' + val[1] + '" value="' + val[0] + '" class="cur">' + val[1] + "</li>"; } else if (val[1].toUpperCase().indexOf(searchText.toUpperCase()) >= 0) { nextStr += '<li title="' + val[1] + '" value="' + val[0] + '">' + val[1] + "</li>"; } }); dataInfo = preStr + nextStr; if ($("#" + objId).length == 0) { $("body").append("<div id='"+ objId +"' class='checkSelect-UL'><ul>"+ dataInfo +"</ul></div>"); thisObj.after('<input type="hidden" id="checkSelect-hidden-'+ id +'" name="'+ id +'" />') } else { $("#" + objId + " ul").html(dataInfo); //设置搜索后的显示列表的高度 if ($("#" + objId + " li").length > 0) { h = searchText == "" ? options.maxHeight : $("#" + objId).find("li").length * options.liHeight; $("#" + objId).height(h).show(); } else { $("#" + objId).hide(); //搜索不到隐藏 } } } //实现键盘操作 function upDownKey(keyCode) { var preObj, currObj, nextObj, ulScrollTop, len = $("#" + objId + " li").length; if (keyCode == 13) { //ENTER if (moveNum >= len) moveNum = moveNum - 1; currObj = $("#" + objId + " li:eq("+ moveNum +")"); var thisVal = currObj.attr("value"); if (!currObj.hasClass("cur")) { currObj.removeClass().addClass("cur"); if ($.inArray(thisVal + "", value_arr) == -1) { value_arr.push(thisVal + ""); title_arr.push(currObj.text()); } } else { currObj.removeClass("cur"); if ($.inArray(thisVal + "", value_arr) != -1) { unsetArray(thisVal, value_arr); unsetArray(currObj.text(), title_arr); } } } else if (keyCode == 38) { //UP moveNum --; if (moveNum <= 0) moveNum = 0; if (moveNum >= len-1 || moveNum > len) moveNum = moveNum - 1; $("#" + objId + " li").removeClass("sel"); currObj = $("#" + objId + " li:eq("+ moveNum +")"); nextObj = $("#" + objId + " li:eq("+ (moveNum + 1) +")"); nextObj.removeClass("sel"); currObj.addClass("sel"); } else if (keyCode == 40) { //DOWN moveNum ++; preObj = $("#" + objId + " li:eq("+ (moveNum - 1) +")"); currObj = $("#" + objId + " li:eq("+ moveNum +")"); if (moveNum > len) moveNum = len -1; if (moveNum < len) { (moveNum-1 > 0) && preObj.removeClass("sel"); currObj.addClass("sel"); } } ulScrollTop = moveNum * options.liHeight; $("#" + objId).get(0).scrollTop = ulScrollTop || 0; } function unsetArray(ele, arr) { for (var num = 0, i = 0; i < arr.length; ++i) { if (arr[i] == ele) num = i; } arr.splice(num, 1); } function log(msg) { window.console && console.log(msg); } }; })(jQuery);
全部代码可点击此处 下载