zoukankan      html  css  js  c++  java
  • js实现的联想输入

      以前也写过一个jQuery的这种插件,但是很多地方根本不用jQuery,这个功能也有很多其它库支持,但是为了用这个功能而加载很多js插件,这样效率明显下降了很多,而且这个东西平时也很常用,所以一决心自己写了个相对比较独立的。

    完成有以下功能:

    • 输入字符会把以输入字符开头的提示出来。
    • 支持上下方向键选择提示选项,支持循环
    • 支持绑定一个数组提示,支持ajax传递输入框值请求数据。
    • 支持多个选择的dom元素一块绑定数据实现输入提示。各dom元素也可以单独绑定自己的数据实现输入提示,互不影响。
    • 支持中文。

          首先是js的核心部分,其各部分都有较详细的说明,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    ;(function(window){
    /* 插件开始 */
    var autoComplete=function(o){
        var handler=(function(){
            var handler=function(e,o){ return new handler.prototype.init(e,o); };/* 为每个选择的dom都创建一个相对应的对象,这样选择多个dom时可以很方便地使用 */
            handler.prototype={
                e:null, o:null, timer:null, show:0, input:null, popup:null,
                init:function(e,o){/* 设置初始对象 */
                    this.e=e, this.o=o,
                    this.input=this.e.getElementsByTagName(this.o.input)[0],
                    this.popup=this.e.getElementsByTagName(this.o.popup)[0],
                    this.initEvent();/* 初始化各种事件 */
                },
                match:function(quickExpr,value,source){/* 生成提示 */
                    var li = null;
                    for(var in source){
                        if( value.length>0 && quickExpr.exec(source[i])!=null ){
                            li = document.createElement('li');
                            li.innerHTML = '<a href="javascript:;">'+source[i]+'</a>';
                            this.popup.appendChild(li);
                        }
                    }
                    if(this.popup.getElementsByTagName('a').length)
                        this.popup.style.display='block';
                    else
                        this.popup.style.display='none';
                },
                ajax:function(type,url,quickExpr,search){/* ajax请求远程数据 */
                    var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
                    xhr.open(type,url,true);/* 同异步在此修改 */
                    xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
                    var that=this;
                    xhr.onreadystatechange = function(){
                        if(xhr.readyState==4) {
                            if(xhr.status==200) {
                                var data = eval(xhr.responseText);
                                that.match(quickExpr,search,data);/* 相同于成功的回调函数 */
                            }else{
                                alert("请求页面异常!");/* 请求失败 */
                            }
                        }
                    };
                    xhr.send(null);
                },
                fetch:function(ajax,search,quickExpr){
                    var that=this;
                    this.ajax(ajax.type,ajax.url+search,quickExpr,search);
                },
                initEvent:function(){/* 各事件的集合 */
                    var that=this;
                    this.input.onfocus = function(){
                        if(this.inputValue) this.value = this.inputValue;
                        var value=this.value, quickExpr=RegExp('^'+value,'i'), self=this;
                        var els = that.popup.getElementsByTagName('a');
                        if(els.length>0) that.popup.style.display = 'block';
                        that.timer=setInterval(function(){
                            if(value!=self.value){/* 判断输入内容是否改变,兼容中文 */
                                value=self.value;
                                that.popup.innerHTML='';
                                if(value!=''){
                                    quickExpr=RegExp('^'+value);
                                    if(that.o.source) that.match(quickExpr,value,that.o.source);
                                    else if(that.o.ajax) that.fetch(that.o.ajax,value,quickExpr);
                                }
                            }
                        },200);
                    };
                    this.input.onblur = function(){/*  输入框添加事件 */
                        if(this.value!=this.defaultValue) this.inputValue = this.value;
                        clearInterval(that.timer);
                        var current=-1;/* 记住当前有焦点的选项 */
                        var els = that.popup.getElementsByTagName('a');
                        var len = els.length-1;
                        var aClick = function(){
                            that.input.inputValue = this.firstChild.nodeValue;
                            that.popup.innerHTML='';
                            that.popup.style.display='none';
                            that.input.focus();
                        };
                        var aFocus = function(){
                            for(var i=len; i>=0; i--){
                                if(this.parentNode===that.popup.children[i]){
                                    current = i;
                                    break;
                                }
                            }
                            //that.input.value = this.firstChild.nodeValue;
                            for(var in that.o.elemCSS.focus){
                                this.style[k] = that.o.elemCSS.focus[k];
                            }
                        };
                        var aBlur= function(){
                            for(var in that.o.elemCSS.blur)
                                this.style[k] = that.o.elemCSS.blur[k];
                        };
                        var aKeydown = function(event){
                            event = event || window.event;/* 兼容IE */
                            if(current === len && event.keyCode===9){/* tab键时popup隐藏 */
                                that.popup.style.display = 'none';
                            }else if(event.keyCode==40){/* 处理上下方向键事件方便选择提示的选项 */
                                current++;
                                if(current<-1) current=len;
                                if(current>len){
                                    current=-1;
                                    that.input.focus();
                                }else{
                                    that.popup.getElementsByTagName('a')[current].focus();
                                }
                            }else if(event.keyCode==38){
                                current--;
                                if(current==-1){
                                    that.input.focus();
                                }else if(current<-1){
                                    current = len;
                                    that.popup.getElementsByTagName('a')[current].focus();
                                }else{
                                    that.popup.getElementsByTagName('a')[current].focus();
                                }
                            }
                        };
                        for(var i=0; i<els.length; i++){/* 为每个选项添加事件 */
                            els[i].onclick = aClick;
                            els[i].onfocus = aFocus;
                            els[i].onblur = aBlur;
                            els[i].onkeydown = aKeydown;
                        }
                    };
                    this.input.onkeydown = function(event){
                        event = event || window.event;/* 兼容IE */
                        var els = that.popup.getElementsByTagName('a');
                        if(event.keyCode==40){
                            if(els[0]) els[0].focus();
                        }else if(event.keyCode==38){
                            if(els[els.length-1]) els[els.length-1].focus();
                        }else if(event.keyCode==9){
                            if(event.shiftKey==true) that.popup.style.display = 'none';
                        }
                    };
                    this.e.onmouseover = function(){ that.show=1; };
                    this.e.onmouseout = function(){ that.show=0; };
                    addEvent.call(document,'click',function(){
                        if(that.show==0){
                            that.popup.style.display='none';
                        }
                    });/* 处理提示框dom元素不支持onblur的情况 */
                }
            };
            handler.prototype.init.prototype=handler.prototype;/* JQuery style,这样我们在处的时候就不用每个dom元素都用new来创建对象了 */
            return handler;/* 把内部的处理函数传到外部 */
        })();
        if(this.length){/* 处理选择多个dom元素 */
            for(var a=this.length-1; a>=0; a--){/* 调用方法为每个选择的dom生成一个处理对象,使它们不互相影响 */
                handler(this[a],o);
            }
        }else{/* 处理选择一个dom元素 */
            handler(this,o);
        }
        return this;
    };
    return window.autoComplete = autoComplete;/* 暴露方法给全局对象 */
    /* 插件结束 */
    })(window);

          其中了一些全局的自定义函数,如addEvent和在例子中将要用到的getElementsByClassName函数如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    var getElementsByClassName = function (searchClass, node, tag) {/* 兼容各浏览器的选择class的方法;(写法参考了博客园:http://www.cnblogs.com/rubylouvre/archive/2009/07/24/1529640.html,想了解更多请看这个地址) */
        node = node || document, tag = tag ? tag.toUpperCase() : "*";
        if(document.getElementsByClassName){/* 支持getElementsByClassName的浏览器 */
            var temp = node.getElementsByClassName(searchClass);
            if(tag=="*"){
                return temp;
            else {
                var ret = new Array();
                for(var i=0; i<temp.length; i++)
                    if(temp[i].nodeName==tag)
                        ret.push(temp[i]);
                return ret;
            }
        }else{/* 不支持getElementsByClassName的浏览器 */
            var classes = searchClass.split(" "),
                elements = (tag === "*" && node.all)? node.all : node.getElementsByTagName(tag),
                patterns = [], returnElements = [], current, match;
            var i = classes.length;
            while(--i >= 0)
                patterns.push(new RegExp("(^|\s)" + classes[i] + "(\s|$)"));
            var j = elements.length;
            while(--j >= 0){
                current = elements[j], match = false;
                for(var k=0, kl=patterns.length; k<kl; k++){
                    match = patterns[k].test(current.className);
                    if(!match) break;
                }
                if(match) returnElements.push(current);
            }
            return returnElements;
        }
    };
    var addEvent=(function(){/* 用此函数添加事件防止事件覆盖 */
        if(document.addEventListener){
            return function(type, fn){ this.addEventListener(type, fn, false); };
        }else if(document.attachEvent){
            return function(type,fn){
                this.attachEvent('on'+type, function () {
                    return fn.call(this, window.event);/* 兼容IE */
                });
            };
        }
    })();

     原文地址: http://www.cnblogs.com/jaiho/archive/2011/02/28/js_autocomplete.html

    如果忘记,在自己的语言精髓文件夹里

  • 相关阅读:
    递归树结构封装
    Excel父子数据导入
    资产类标准数据源抽取顺序
    资产模型数据初始化时应注意的事项
    Input Parameters and Variables in SAP HANA Modeling
    2LIS_03_BX数据源的用处及抽取步骤
    BW资产数据源抽取顺序
    MM物料移动BW数据源介绍
    关于BW newGL datasource
    使用SLT系统抽数到hana系统
  • 原文地址:https://www.cnblogs.com/yangheng/p/6015586.html
Copyright © 2011-2022 走看看