基于jquery扩展之漂亮的智能感知控件

在我们使用百度搜索时,输入关键会提示一列相关的关键字,我们可以快速指向需要查找的关键字,这样操作相当的方便,我认为这是一个很酷的一个用户体验。当然很多人在做开发自己的项目时也会加入这项功能来增强自己的网站更好的应用性。当然我们不能一味追求用户体验度的完美而拖慢项目的进度来博取用户的一时好感。如果说现在已经有一个很好的用户体验控件,你会如何选择呢? 那就让我们加入进去吧!!!


首先在实现这个控件的前期我们需要分析这个控件实现思路:

1。输入关键字检索,获取相应的数据;可加载客户端数据或服务端数据。

2。绑定数据包含:列表绑定,单行信息绑定。

3。鼠标选择行信息事件,将数据绑定到文本控件中。

4。关闭控件,清除下拉列表控件。

5。键盘上下键操作事件。


实现的示例图如下:



根据上面的思路完成相应功能代码如下:

1。Css样式:

.search_html{float:left;position:absolute;padding:4px;border:1px solid #ccc;border-top:0px;z-index:4;background-color:#fff;}
.search_html ul{float:left;margin:0px;padding:0px;}
.search_html ul li{float:left;list-style:none;display:inline;cursor:pointer;}
.search_html ul li.search_li{float:left;width:100%;padding:6px 0;text-indent:6px;overflow:hidden;}
.search_html ul li.hover{background-color:#666;color:#fff;}

/*搜索下拉*/
.con_user ul li em i{background: url(/img/Icon_BG.png) no-repeat scroll -99px -74px;height: 20px;margin: 3px 5px;width: 20px;}
.con_user ul li em.em_input{float:left;font-style:normal;width:190px;border: 1px solid #CCCCCC; border-radius: 2px 2px 2px 2px;box-shadow: 1px 2px 4px #888888;padding-left:0px;}
.manage .con_user ul li em input.txt{border:0px;border-radius:0px;box-shadow:none;width:150px;}
.con_user ul li em i{ float: right; background-position: -213px -75px;height: 20px; margin: 2px 0; width: 20px;cursor: pointer;}
.search_html{z-index:1020;box-shadow: 1px 4px 4px #888888; border-radius: 0 0 2px 2px;text-align:left;}
.search_html ul{width:182px;*width:176px;}
.search_html ul li{margin:0px;}
.none{display:none;}

2.Js代码调用部分

//原始智能感知控件
function IntelligentPerceive() {
    this.myTag;
    this.input;
    this.url;
    this.txt_old;
    this.index;
    this.delay;
    this.iskeyup;
    this.items;

    var _obj = this, _input, _index, _url, _myTag, _delay, _items;
    var timer;
    this.init_fun = function () {
        _input = _obj.input;
        _myTag = _obj.myTag;
        _index = _obj.index;
        //请求地址
        _url = _obj.url;
        //数据对象
        _items = _obj.items;
        _delay = _obj.delay == undefined ? 200 : _obj.delay; //默认值0.2秒
        if (_index == undefined) _index = -1;

        _myTag.unbind("click");
        _myTag.click(function () {
            _obj.close();
        });

        if (_obj.iskeyup == false) return;
        //输入框事件
        _input.unbind("keyup");
        timer = 0;
        _input.keyup(function (e) {
            var key = $(this);
            if (!_obj.keyup(e)) return;
            //延迟搜索
            if (timer > 0) clearTimeout(timer);
            timer = setTimeout(function () {
                var value = key.val();
                if (_obj.txt_old && value == _obj.txt_old) return false;
                _obj.txt_old = value;
                if (value == "") {
                    _input.attr("_id", 0);
                    _obj.close();
                } else
                    _obj.show(e);
            }, _delay);
            _obj.keyup_Callback(_input);
        });
    }
    //行单击事件
    this.list_selected = function (index) {
        var row = $(".search_html .search_li:eq(" + index + ")");
        $('.search_html').find('.search_li').removeClass('hover');
        row.addClass('hover');
        _obj.bind_input(row);
        _input.attr("_id", row.attr('_id'));
        _obj.click_Callback(_input, row, index);
    }
    //行单击回调事件
    this.click_Callback = function (input, row, index) {

    }
    //键盘输入回调事件
    this.keyup_Callback = function (input) { }
    //输入框赋值方法
    this.bind_input = function (row) {
        _input.val(row.text());
    }
    //上下选择按钮事件
    this.keyup = function (e) {
        var _len = $(".search_html .search_li").length;
        switch (e.keyCode) {
            case 38: if (--_index < 0) _index = _len - 1; break; //
            case 40: if (++_index >= _len) _index = 0; break; //
            case 13:
                {//回车
                    _obj.list_selected(_index);
                    _obj.close();
                    return false;
                }; break;
            default:
                {
                    _input.attr("_id", 0);
                    return true;
                }
        }
        //输入框获取值
        _obj.list_selected(_index);
        return false;
    };

    //列表绑定模板
    this.bindHtml = function () {
        return '<div class="search_html"><ul></ul></div>';
    }
    //行绑定数据模板
    this.bindRow = function (data) {
        return '<li class="search_li" _id="' + data.id + '">' + data.real_name + '</li>';
    };
    //搜索结果显示
    this.show = function (e) {
        _obj.close();
        _myTag.append(_obj.bindHtml());
        $(".search_html").css("top", _input.offset().top + (isNaN(_input.outerHeight()) ? _input.innerHeight() : _input.outerHeight()) - 2);
        $(".search_html").css("left", _input.offset().left - 1);
        //列表事件
        var list_click = function (ul) {
            //行单击事件
            ul.find(".search_li").click(function () {
                _index = $(this).index();
                _obj.list_selected(_index);
                _obj.close();
            });
            //鼠标移入行事件
            ul.find(".search_li").hover(function () {
                _index = $(this).index();
                $(this).addClass("hover");
            }, function () {
                $(this).removeClass("hover");
            });
        }

        if (_items != null && _items != undefined) {
            var ul = $('.search_html ul'), html = '';
            ul.html('');
            //绑定数据
            if (_items.length == 0) { _obj.close(); return; }
            $.each(_items, function (i, item) {
                if (item.real_name.indexOf(_input.val()) > -1) {
                    html += _obj.bindRow(item);
                }
            });
            ul.append(html);
            //添加事件
            list_click(ul);
        } else {
            requestAPI(_url, "key=" + escape(_input.val()), function (json) {
                var data = json.description ? json.description : json.list;
                _index = -1;
                var ul = $('.search_html ul'), html = '';
                ul.html('');
                if (data.length == 0) _obj.close();
                //绑定数据
                for (var i = 0; i < data.length; i++) {
                    html += _obj.bindRow(data[i]);
                }
                ul.append(html);
                list_click(ul);
            }, function (json) { });
        }
    }
    //关闭
    this.close = function () {
        if (_myTag && _myTag.find('.search_html').length > 0)
            _myTag.find('.search_html').remove();
    }
}

//二次封装智能感知控件
function DropdownItem(item) {
    //下拉搜索 item {dropdown:,input:,tag:,url:,bindRow:}
    var _dropdown = item.dropdown, _input = item.input, _myTag = item.tag ? item.tag : $('body'), _url = item.url;
    if (_dropdown == undefined || _input == undefined) return; 
    //行绑定事件
    var fun_bindRow = item.bindRow ? item.bindRow : function (data) { return '<li class="search_li" _id="' + data.id + '">' + data.name + '</li>'; };
    //行单击事件
    var bind_input = item.clickRow ? item.clickRow : function (row) {
        _input.val(row.html());
        _input.attr('_id', row.attr('_id'));
        _dropdown.addClass('none');
        //_dropdown.hide("fast", function () { _dropdown.addClass('none'); });
    };

    var intell = new IntelligentPerceive();
    intell.myTag = _myTag;
    intell.input = _input;
    intell.url = _url;
    intell.keyup_Callback = function (input) { input.val() == "" ? _dropdown.removeClass('none') : _dropdown.addClass('none'); };
    //行绑定数据模板
    intell.bindRow = fun_bindRow
    //行单击事件
    intell.bind_input = bind_input;
    intell.init_fun();
    //下拉选择指派人
    _dropdown.click(function () {
        if (_input.attr('_id') != undefined && _input.attr('_id') != 0) return;
        if ($('.search_html').length > 0) return;
        //显示下拉列表
        var dropdown = new IntelligentPerceive();
        dropdown.myTag = _myTag;
        dropdown.input = _input;
        dropdown.url = _url; //需要切换地址
        dropdown.delay = 10;
        dropdown.iskeyup = false;
        dropdown.bindRow = fun_bindRow;
        dropdown.bind_input = bind_input;
        dropdown.init_fun();
        //清除单击事件
        dropdown.myTag.unbind("click");
        dropdown.show();
        var btn_drop = $(this);
        //重新绑定单击事件
        $('.content').unbind('click').click(function (event) {
            var left = btn_drop.offset().left, top = btn_drop.offset().top,
            width = isNaN(btn_drop.outerWidth()) ? btn_drop.innerWidth() : btn_drop.outerWidth(),
            height = isNaN(btn_drop.outerHeight()) ? btn_drop.innerHeight() : btn_drop.outerHeight();
            if ((event.pageX >= left && event.pageX <= left + width) && (event.pageY >= top && event.pageY <= top + height)) return;
            _input.val() == "" ? _dropdown.removeClass('none') : _dropdown.addClass('none');
            dropdown.close();
        });
    });
}

3。示例代码如下:

前端html布局

<li><font>产品类型:</font><em class="em_input"><input class="txt pro_type" type="text" maxlength="20" _id='0' /><i></i></em></li>

脚本实例化调用

//类型下拉搜索
    var pro_type = $('.pro_type');
    new DropdownItem({ dropdown: $('.con_user li em i'), //下拉按钮对象
        input: pro_type, //输入框对象
        tag: $('body'), //操作区域对象
        url: "/Handler/product/ProductType.ashx?type=list&t=1", //异步请求地址
        bindRow: function (data) {
            return '<li class="search_li" _id="' + data.pt_id + '">' + data.type_name + '</li>';
        } //绑定地址
    });

本文当中还调用到jquery中所封装的ajax函数(requestAPI)

//=============================基于jquery函数======================================
//异步提交数据
function requestAPI(requestURL, requestData, successFun, errorFun, async) {
    var jsonFun = new JsonFun(successFun, errorFun);
    $.ajax({
        url: requestURL,
        cache: false,
        type: "POST",
        data: requestData + "&n=" + new Date().getSeconds(),
        dataType: "json",
        success: jsonFun.success,
        error: jsonFun.error,
        async: async != false
    });
}
//异步回调函数
function JsonFun(successFun, errorFun) {
    return {
        success: function (json) {
            if (json != undefined && json.result_state == false) {
                if (errorFun != undefined) {
                    errorFun(json);
                }
                else {
                    var tips = new Tips();
                    tips.myHtml = getJsonMsg(json);
                    tips.show();
                }
            }
            else {
                successFun(json);
            }
        },
        error: function (XMLHttpRequest) {
            var desc = XMLHttpRequest.responseText;

            desc = desc.replace(/[\f\n\r\t\v]/g, "");
            desc = desc.replace(/[ ]{1,}/g, " ");
            desc = desc.replace(/<\/?.+?>/g, "<div style=\"height:1px;overflow:hidden;\"></div>");
            desc = desc.replace(/body\s+{(.*)}/g, "");

            if (errorFun != undefined && errorFun != null && desc.trim().length > 0) {
                errorFun({ "state": false, "description": "系统出现异常,请稍后再试!<a href=\"javascript:$('.tips_exception').html().runCode()\">查看异常信息</a><div class=\"tips_exception none\">" + desc + "</div>" });
            }
            else if (desc.trim().length > 0) {
                var tips = new Tips();
                tips.myHtml = getJsonMsg(json);
                tips.show();
            }
        }
    };
}

 

以下为示例教程IntelligentPerceive()

html代码

<head>

    <title></title>

    <link rel="stylesheet" type="text/css" href="/_css/Intelligent.css" />

    <link href="/_css/manage.css" rel="stylesheet" type="text/css" />

    <script src="/_js/jquery-1.8.2.min.js" type="text/javascript"></script>

    <script src="/_js/Valid.js" type="text/javascript"></script>

    <script src="/_js/common.js" type="text/javascript"></script>

    <script src="/_JS/Intelligent.js" type="text/javascript"></script>

    <script src="download.js" type="text/javascript"></script>

</head>

<body>

<div class="div_search">

    <em class="em_input"><input class="txt serach_user" type="text"

   maxlength="20" _id='0' /><i></i></em>

</div>

</body>

bindRow()

行绑定事件,显示列表,将加载的json数据绑定到下拉框中。

示例:

var serach_user = $('.serach_user');
new DropdownItem({ dropdown: serach_user.next(),
   input: serach_user,
   tag: $('body'),
   default_value: '请输入内容’,
   class_name: 'search_size',
   url: "/handler/users/User.ashx?type=list&index=1&size=6&total=6&key=" + "",
   bindRow: function (data) {
      return '<li class="search_li" _id="{0}">{1}</li>'.format(data.user_id, data.user_name);
   }
});

展示效果:

clickRow()

行单击事件,选中下拉框数据时将选中的id值和内容绑定到输入框内。

示例:

var serach_user = $('.serach_user');
new DropdownItem({ dropdown: serach_user.next(),
   input: serach_user,
   tag: $('body'),
   default_value: '请输入内容’,
   class_name: 'search_size',
   url: "/handler/users/User.ashx?type=list&index=1&size=6&total=6&key=" + "",
   bindRow: function (data) {
      return '<li class="search_li" _id="{0}">{1}</li>'.format(data.user_id, data.user_name);
   }, clickRow: function (row)
   {
      alert("选择行");
   } });

展示效果:

keyup_Callback(input)

键盘输入回调事件,在输入框输入关键字,查询包含关键字的记录显示在列表中。

示例:

var serach_user = $('.serach_user');
new DropdownItem({ dropdown: serach_user.next(),
   input: serach_user,
      tag: $('body'),
      default_value: '请输入内容’,
      class_name: 'search_size',
      url: "/handler/users/User.ashx?type=list&index=1&size=6&total=6&key=" + "",
      bindRow: function (data) {
         return '<li class="search_li" _id="{0}">{1}</li>'.format(data.user_id, data.user_name);
      }, keyup_Callback: function (input)
      {
         alert("键盘输入事件");
      } });

展示效果:

rowHover(index)

移入行事件,鼠标移入记录执行的操作。

示例:

var serach_user = $('.serach_user');
   new DropdownItem({ dropdown: serach_user.next(),
   input: serach_user,
   tag: $('body'),
   default_value: '请输入内容’,
   class_name: 'search_size',
   url: "/handler/users/User.ashx?type=list&index=1&size=6&total=6&key=" + "",
   bindRow: function (data) {
      return '<li class="search_li" _id="{0}">{1}</li>'.format(data.user_id, data.user_name);
   }, rowHover: function (index)
   {
      alert("移入行事件");
   } });

展示效果:

closed_Callback()

关闭后回调事件。传递回调事件,可以拓展关闭下拉框后执行的操作。

示例:

var serach_user = $('.serach_user');
new DropdownItem({ dropdown: serach_user.next(),
   input: serach_user,
   tag: $('body'),
   default_value: '请输入内容’,
   class_name: 'search_size',
   url: "/handler/users/User.ashx?type=list&index=1&size=6&total=6&key=" + "",
   bindRow: function (data) {
      return '<li class="search_li" _id="{0}">{1}</li>'.format(data.user_id, data.user_name);
   }, closed_Callback: function ()
   {
      alert("关闭后回调事件");
   } });

展示效果:

下载地址:

js智能下拉框控件

http://www.tiaoceng.com/assemblydetail_2.htmll

新浪微博(求关注)地址:

http://weibo.com/zhengdjin

posted @ 2016-06-15 10:27  跳层  阅读(499)  评论(0编辑  收藏  举报