首页 > 网站 > WEB开发 > 正文

自己手写的自动完成js类

2024-04-27 14:21:45
字体:
来源:转载
供稿:网友

自己手写的自动完成js类

  在web开发中,为了提高用户体验,会经常用到输入框的自动完成功能,不仅帮助用户进行快速输入,最重要的是帮助那些“记不全要输入什么”的用户进行选择。这个功能有很多插件已经实现了,为了适应项目的特殊需求,决定自己编写一个具备通用性、扩展性和灵活性的自动完成类,就当是边写边学习了,一举两得。该功能是比较简单的,核心是数据获取方式和导航的实现,简单写了一个,经测试非常好用,还有很多地方需要修改和改进,例如:在原型中只暴露init方法即可,其他方法都需要放到私有空间内,不让用户访问到,这个以后再完善吧。啥也不说了,小二,上菜:

代码如下:(已更新,最新代码请参考:https://github.com/zjh-neverstop/AutoCompleteMulti)

  1 /**  2  * 实现自动完成功能的js类  3  * 1、数据获取方式:设置静态数据集、Ajax方式、自定义数据获取函数  4  * 2、可以控制是否启用匹配项的循环选择  5  * 3、可以控制是否使用默认静态数据集,在获取动态数据失败的情况下会显示    7  */  8   9 (function(){ 10  11     //封装使用频繁的变量,在构造函数中进行初始化 12     var commonObj = {}; 13  14     /** 15      * 构造函数 16      * @param option 17      * @constructor 18      */ 19     function AutoComplete(option) { 20         //需要实现自动完成功能的页面控件ID 21         this.controlId = option.controlId; 22  23         //匹配结果div的id 24         this.resultDivId = option.resultDivId; 25  26         //当前选中的项索引,第一项索引为0 27         this.index = -1; 28  29         //静态数据集 30         this.datas = option.datas; 31          32         //动态获取的数据集 33         this.dynamicDatas = null; 34  35         //服务器端地址 36         this.serverUrl = option.serverUrl; 37  38         //匹配结果集合 39         this.resultDatas = null; 40  41         //ajax请求数据 42         this.ajaxRequestData = option.ajaxRequestData; 43  44         //主要用在一个后台页面处理多个前端自动完成请求的情况,根据此字段调用具体的后台方法 45         this.actionName = option.actionName; 46  47         //是否可以循环选择 48         this.circleChoose = option.circleChoose || "true"; 49  50         //是否从服务器端获取数据 51         this.serverEnabled = option.serverEnabled || "false"; 52          53         //是否使用静态数据 54         //一般情况下,自动完成都是获取动态数据的,开启这个标志后,在获取动态数据失败的情况下会使用静态数据,默认为false 55         this.useStaticDatas = option.useStaticDatas||"false";     56          57         //驱动函数 58         this.drivenFuc = null; 59  60         //自定义数据获取方法 61         this.getCompleteDatas = function (){ 62             if( typeof option.getCompleteDatas === 'function' ){ 63                 return option.getCompleteDatas(); 64             } 65             else{ 66                 return null; 67             } 68              69         }; 70  71  72         //私有变量,封装后面常用的4个变量 73         //var commonObj = {}; 74  75         //通过匿名函数来构造一个类似面向对象语言中的只读属性 76         //初始化commonObj变量 77         //注意:匿名函数中的this指向windows对象,这里需要将AutoComplete对象的引用赋值给that 78         (function(that){ 79             commonObj =  { 80                 control : document.getElementById(that.controlId), 81                 results : document.getElementById(that.resultDivId), 82                 jControl : $(document.getElementById(that.controlId)), 83                 jResults : $(document.getElementById(that.resultDivId)) 84             }; 85         })(this); 86  87         //只读属性 88         /*this.getCommonObj = function(){ 89             return commonObj; 90         }*/ 91  92     } 93  94     /** 95      * 原型方法,除了init方法和构造函数外,其他方法均需要私有化,待完善... 96      */ 97     AutoComplete.PRototype = { 98  99         //指定构造函数100         constructor: AutoComplete,101 102         //获取事件对象103         getEvent: function() {104             return window.event || arguments[0]; //event ? event : window.event;105         },106 107         //获取事件源108         getTarget: function(event) {109             return event.target || event.srcElement;110         },111 112         /**113          * 计算div的偏移量114          * @param obj115          * @returns {{left: (Number|number), top: (Number|number)}}116          */117         getOffset: function(obj) {118             var x = obj.offsetLeft || 0;119             var y = obj.offsetTop || 0;120             var temp = obj;121             while (temp.offsetParent) {122                 temp = temp.offsetParent;123                 x += temp.offsetLeft;124                 y += temp.offsetTop;125             }126             //alert("x:"+x+" y:"+y);127             return { left: x, top: y };128         },129 130         /**131          * 将tagetDiv定位到sourceDiv下方,与sourceDic左对齐,宽度一致132          * @param sourceDiv133          * @param targetDiv134          */135         positionDiv: function(sourceDiv, targetDiv) {136             var obj = document.getElementById(sourceDiv);137             var xy = this.getOffset(obj);138             $("#" + targetDiv).CSS("left", xy.left);139             $("#" + targetDiv).css("width", $("#" + sourceDiv).outerWidth());140             $("#" + targetDiv).css("top", (xy.top + $("#" + sourceDiv).outerHeight()));141 142         },143 144         init: function() {145             var control = document.getElementById(this.controlId);146             var results = document.getElementById(this.resultDivId);147             var jControl = $(control);148             var jResults = $(results);149             var autoThisObj = this;150 151             document.onclick = function(event) {152                 //$("#"+resultDivId).hide();153                 var target = autoThisObj.getTarget(autoThisObj.getEvent(event));154                 //alert(target.id);155                 if (target.id == autoThisObj.controlId) {156                     return false;157                 }158                 autoThisObj.clearResults();159             }160 161             //兼容ie(ie浏览器下,当按下up与down键时,输入框会失去焦点,导致up与down键不起作用)162             jResults.bind("keydown", function(event) {163                 jControl.keydown();164                 return false;165             });166 167 168             //给指定控件绑定keyup事件169             $("#" + autoThisObj.controlId).bind("keyup", function(event) {170                 var e = autoThisObj.getEvent(event);171                 var keyCode = e.keyCode;172                 if ((keyCode == '40' || keyCode == '38' || keyCode == '37' || keyCode == '39' || keyCode == '13' || keyCode == '9')) {173                     return false;174                 }175 176                 autoThisObj.index = -1;177                 results.scrollTop = 0;178 179                 var keyWord = $.trim(jControl.val());180                 if (keyword.length == 0) {181                     //jResults.hide();182                     autoThisObj.clearResults();183                     return;184                 }185                 186                 //获取动态数据集,自定义函数的优先级最高187                 var autoDatas = autoThisObj.getCompleteDatas();//调用自定义数据获取函数188                 if( (autoDatas instanceof Array) && (autoDatas.length > 0) ){  189                     autoThisObj.dynamicDatas = autoDatas;190                 }191                 else if(autoThisObj.serverEnabled=="true"){  //服务器端获取数据192                     autoThisObj.getAjaxDatas();  193                 }194                 195                 //196                 if(autoThisObj.dynamicDatas!=null){197                     autoThisObj.generateHtml(autoThisObj.dynamicDatas);198                 }199                 else if(autoThisObj.useStaticDatas=="true" && autoThisObj.datas.length>0){200                     autoThisObj.generateHtml(autoThisObj.datas);201                 } 261             }); //end keyup()262 263             this.navigate();264         }, // end init()265 266         /**267          * 定义 up与down 按键功能268          * @param event269          * @param objectId270          * @returns {boolean}271          */272         navigate: function(event) {273 274             var control = document.getElementById(this.controlId);275             var results = document.getElementById(this.resultDivId);276             var jControl = $(control);277             var jResults = $(results);278 279             var autoThisObj = this;280 281             this.keyDownBind(jControl);282 283         },  // end navigate()284 285         /**286          * 给指定jquery元素绑定keydown事件,使其可以进行匹配项的选择287          */288         keyDownBind: function(jObject) {289             var control = document.getElementById(this.controlId);290             var results = document.getElementById(this.resultDivId);291             var jControl = $(control);292             var jResults = $(results);293             var autoThisObj = this;294             jObject.keydown(function(e
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表