基于jQuery的autocomplete(自动补全)类

本文介绍了一个基于JQuery的自动补全插件,支持通过JSON数据动态更新建议列表,并提供了详细的配置选项说明及使用示例。

最近很多人在群里求autocomplete类,那我就献下丑,把自己写的分享一下:

/*! JQuery autocomplete
 * Author: Vilien
 * Date: 2013-7-12
 *
 * !@options {uri:"uri", eachRequest:false, width:0}
 * > 该运行库参数采用jQuery风格,参数说明如下
 *
 * @param uri
 * > 返回json数据的资源地址,必须,可包含一个自动适配变量:key
 * > 取值示例:{uri: "http://abc.com/auto.jsp?words=:key"}
 * > :key将由JS根据输入框输入字符自动解析
 * > uri资源返回的json数据格式必须为 ["字符串1","字符串2","字符串3"...]
 *
 * @param eachRequest
 * > 逐个字符请求资源开关,可省略,缺省为false
 * > 当打开该开关时,用户每输入一个字符,都将向服务器请求一次结果
 * > 关闭该开关(将该值设为false)时,只在输入第一个字符时向服务器请求一次,后续输入将自动过滤
 *
 * @param width
 * > 自动完成显示宽度,可省略,缺省为0 (为零则自动获取)
 * > 缺省状态下,程序会自动获取宽度,但也可以用该选项设定一个固定宽度
 */

;(function($){$.fn.extend({

autocomplete: function(options){

    var defaults = {            ///  缺省配置参数
        uri         : ":key",   ///< 可返回json数据格式的uri,:key将由JS自动解析(例:http://xx/?s=:key)
        eachRequest : false,    ///< 逐个字符请求开关(缺省关闭,即只在输入第一个字符时向服务器请求一次)
        width       : 0         ///< 显示宽度(为零则自动获取)
    };

    /* -============ 自动完成样式 ==========-
     * 可根据需要修改
     */
    var style1 = {
        "border": "1px solid #bbb",
        "background-color": "#fff",
        "line-height": "1.2",
        "cursor": "default"
    };

    /* -============ 自动完成鼠标经过样式 ==========-
     * 可根据需要修改
     */
    var style2 = {
        "background-color": "#ebebeb"
    };

    // 样式处理
    if ($("style[id=autocompletecss]").length<1) {
        var styleText = ".AUTOCOMPLETE{"; // 用于封装style
        for (var i in style1) { styleText += i + ":" + style1[i] + ";"; }
        styleText    += "}.AUTOCOMPLETE p.cur{";
        for (var i in style2) { styleText += i + ":" + style2[i] + ";"; }
        styleText    += "}";
        $("head").append("<style id=\"autocompletecss\" type=\"text/css\">"+styleText+"</style>");
    }

    $(this).each(function(){
        if (!$(this).is(":text")) {return true;}// 检测选中元素是否是单行输入框,不是则退出

        // 初始化
        var settings = $.extend({}, defaults, options); // 合并参数
        var _self = $(this);
        _self.prop("autocomplete", "off"); // 关闭系统自动完成

        var list,
            width= settings.width ? settings.width : _self.innerWidth(),
            wrap = $("<div class=\"AUTOCOMPLETE\"></div>").css({
                "position" : "absolute",
                "z-index" : 9999,
                "width" : width,
                "display" : "none",
                "overflow" : "hidden",
                "text-align" : "left"
            });

        _self.after(wrap);

        // 显示自动完成
        function complete(list, val) {
            wrap.children().remove();
            if (!settings.eachRequest) {
                for (var i in list) {
                    if (list[i].substring(0, val.length) == val) {
                        wrap.append("<p style=\"margin:0;padding:0 5px\">"+list[i]+"</p>");
                    }
                }
            } else {
                for (var i in list) {
                    wrap.append("<p style=\"margin:0;padding:0 5px\">"+list[i]+"</p>");
                }
            }
            var pos = _self.position();
            wrap.css({
                "top" : pos.top + _self.outerHeight(),
                "left" : pos.left
            });
            wrap.find("p").length>0 ? wrap.show() : wrap.hide();
        }

        // 上下键效果
        function walkList(code) {
            var pList = wrap.children("p");
            if (!wrap.is(":visible") && pList.length < 1) {
                return false;
            }
            var idx = wrap.children("p.cur").index();
            code === 40 ? idx++ : 0;
            code === 38 ? idx-- : 0;
            idx >= pList.length ? idx = 0 : 0;
            idx < 0 ? idx = pList.length-1 : 0;
            pList.eq(idx).mouseover();
            return true;
        }
        _self.on("keydown",function(e){
            var code = e.keyCode;
            if (code===40 || code===38) {
                walkList(code);
            } else if (code===13) {
                wrap.children("p.cur").click();
            }
            return true;
        });

        _self.on("keyup",function(e){
            var code = e.keyCode,
                val = $(this).val();

            if (code===40 || code===38 || code===13) {
                return true;
            }
            if (val.length === 0) {
                wrap.hide();
                return true;
            }
            if (val.length > 1 && !settings.eachRequest && list) { // 无需请求
                complete(list, val);
            } else {
                $.getJSON(settings.uri.replace(":key", val), function(result){
                    list = result;
                    complete(list, val);
                })
            }
        });

        $("body").on("click",function(e){
            wrap.hide();
        });

        wrap.on("click", "p", function(){
            _self.val($(this).text());
        });

        wrap.on("mouseover", "p", function(){
            $(this).addClass("cur").siblings().removeClass("cur");
        });

        wrap.on("mouseout", function(){
            $(this).children("p").removeClass("cur");
        });

    });
}

})})(jQuery);

使用方法:

<input id="auto" type="text" />
<script type="text/javascript">
$("#auto").autocomplete({uri:"http://www.mysite.com/autocomplete.php?word=:key"});
</script>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值