基于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);

 

全部代码可点击此处 下载

转载于:https://www.cnblogs.com/yangjinjin/archive/2013/03/06/2946884.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值