js自动完成

源代码来自于: http://down.51cto.com/data/921955  我做了一下修改.

要做一个自动完成的功能,又不想依赖一大堆的js脚本库,我要的是定制的,代码尽可能简洁,方便修改和维护.

网上找过jquery的autocomplate,样式太多,功能太多,我不需要.还有一些数据源分为数组和ajax返回值,数组写死的,我不要.

皇天不负有心人,让我在51上找到这个, 我修改了一下,贴出来跟大家分享一下.

  1 /**
  2 * JavaScript inputSuggest v0.1
  3 * Copyright (c) 2010 snandy
  4 * Blog: http://snandy.javaeye.com/
  5 * QQ群: 34580561
  6 * Date: 2010-09-25 
  7 * Download by http://down.liehuo.net
  8 * 
  9 * new InputSuggest({
 10 *       input         HTMLInputElement 必选
 11 *       data             Array ['sina.cn','sina.com','2008.sina.com','vip.sina.com.cn'] 必选
 12 *       containerCls    容器className
 13 *       itemCls        容器子项className
 14 *       activeCls        高亮子项className
 15 *       width         宽度设置 此项将覆盖containerCls的width
 16 *    opacity        透明度设置 此项将覆盖containerCls的opacity
 17 * });
 18 */
 19 
 20 function InputSuggest(opt) {
 21     this.win = null;
 22     this.doc = null;
 23     this.container = null;
 24     this.items = null;
 25     this.input = opt.input || null;
 26     this.containerCls = opt.containerCls || 'suggest-container';
 27     this.itemCls = opt.itemCls || 'suggest-item';
 28     this.activeCls = opt.activeCls || 'suggest-active';
 29     this.width = opt.width;
 30     this.opacity = opt.opacity;
 31     this.data = opt.data || [];
 32     this.active = null;
 33     this.visible = false;
 34     this.init();
 35 }
 36 InputSuggest.prototype = {
 37     init: function () {
 38         this.win = window;
 39         this.doc = window.document;
 40         this.container = this.$C('div');
 41         this.attr(this.container, 'class', this.containerCls);
 42         this.doc.body.appendChild(this.container);
 43         this.setPos();
 44         var _this = this, input = this.input;
 45 
 46         this.on(input, 'keyup', function (e) {
 47             if (input.value == '') {
 48                 _this.hide();
 49             } else {
 50                 _this.onKeyup(e);
 51             }
 52 
 53         });
 54         // blur会在click前发生,这里使用mousedown
 55         this.on(input, 'blur', function (e) {
 56             _this.hide();
 57         });
 58         this.onMouseover();
 59         this.onMousedown();
 60 
 61     },
 62     $C: function (tag) {
 63         return this.doc.createElement(tag);
 64     },
 65     getPos: function (el) {
 66         var pos = [0, 0], a = el;
 67         if (el.getBoundingClientRect) {
 68             var box = el.getBoundingClientRect();
 69             pos = [box.left, box.top];
 70         } else {
 71             while (a && a.offsetParent) {
 72                 pos[0] += a.offsetLeft;
 73                 pos[1] += a.offsetTop;
 74                 a = a.offsetParent
 75             }
 76         }
 77         return pos;
 78     },
 79     setPos: function () {
 80         var input = this.input,
 81             pos = this.getPos(input),
 82             brow = this.brow,
 83             width = this.width,
 84             opacity = this.opacity,
 85             container = this.container;
 86         container.style.cssText =
 87             'position:absolute;overflow:hidden;left:'
 88             + pos[0] + 'px;top:'
 89             + (pos[1] + input.offsetHeight) + 'px;'
 90         // IE6/7/8/9/Chrome/Safari input[type=text] border默认为2,Firefox为1,因此取offsetWidth-2保证与FF一致
 91             + (brow.firefox ? input.clientWidth : input.offsetWidth - 2) + 'px;';
 92         if (width) {
 93             container.style.width = width + 'px';
 94         }
 95         if (opacity) {
 96             if (this.brow.ie) {
 97                 container.style.filter = 'Alpha(Opacity=' + opacity * 100 + ');';
 98             } else {
 99                 container.style.opacity = (opacity == 1 ? '' : '' + opacity);
100             }
101         }
102     },
103     show: function () {
104         this.container.style.visibility = 'visible';
105         this.visible = true;
106     },
107     hide: function () {
108         this.container.style.visibility = 'hidden';
109         this.visible = false;
110     },
111     attr: function (el, name, val) {
112         if (val === undefined) {
113             return el.getAttribute(name);
114         } else {
115             el.setAttribute(name, val);
116             name == 'class' && (el.className = val);
117         }
118     },
119     on: function (el, type, fn) {
120         el.addEventListener ? el.addEventListener(type, fn, false) : el.attachEvent('on' + type, fn);
121     },
122     un: function (el, type, fn) {
123         el.removeEventListener ? el.removeEventListener(type, fn, false) : el.detachEvent('on' + type, fn);
124     },
125     brow: function (ua) {
126         return {
127             ie: /msie/.test(ua) && !/opera/.test(ua),
128             opera: /opera/.test(ua),
129             firefox: /firefox/.test(ua)
130         };
131     } (navigator.userAgent.toLowerCase()),
132     onKeyup: function (e) {
133         var container = this.container, input = this.input, iCls = this.itemCls, aCls = this.activeCls;
134         if (this.visible) {
135             switch (e.keyCode) {
136                 case 13: // Enter
137                     if (this.active) {
138                         input.value = this.active.firstChild.data;
139                         this.hide();
140                     }
141                     return;
142                 case 38: // 方向键上
143                     if (this.active == null) {
144                         this.active = container.lastChild;
145                         this.attr(this.active, 'class', aCls);
146                         input.value = this.active.firstChild.data;
147                     } else {
148                         if (this.active.previousSibling != null) {
149                             this.attr(this.active, 'class', iCls);
150                             this.active = this.active.previousSibling;
151                             this.attr(this.active, 'class', aCls);
152                             input.value = this.active.firstChild.data;
153                         } else {
154                             this.attr(this.active, 'class', iCls);
155                             this.active = null;
156                             input.focus();
157                             input.value = input.getAttribute("curr_val");
158                         }
159                     }
160                     return;
161                 case 40: // 方向键下
162                     if (this.active == null) {
163                         this.active = container.firstChild;
164                         this.attr(this.active, 'class', aCls);
165                         input.value = this.active.firstChild.data;
166                     } else {
167                         if (this.active.nextSibling != null) {
168                             this.attr(this.active, 'class', iCls);
169                             this.active = this.active.nextSibling;
170                             this.attr(this.active, 'class', aCls);
171                             input.value = this.active.firstChild.data;
172                         } else {
173                             this.attr(this.active, 'class', iCls);
174                             this.active = null;
175                             input.focus();
176                             input.value = input.getAttribute("curr_val");
177                         }
178                     }
179                     return;
180 
181             }
182 
183         }
184         if (e.keyCode == 27) { // ESC键
185             this.hide();
186             input.value = this.attr(input, 'curr_val');
187             return;
188         }
189         if (input.value.indexOf('@') != -1) { return; }
190         this.items = [];
191 
192         if (this.attr(input, 'curr_val') != input.value) {
193             this.container.innerHTML = '';
194             for (var i = 0, len = this.data.length; i < len; i++) {
195              
196                 if (this.data[i].toLowerCase().indexOf(input.value.toLowerCase()) >= 0) {
197                     var item = this.$C('div'); //create div
198                     this.attr(item, 'class', this.itemCls);
199                     //item.innerHTML = input.value + '@' + this.data[i];
200                     item.innerHTML =  this.data[i]; // 修改源代码处
201                     this.items[i] = item;
202                     this.container.appendChild(item);
203                 }
204             }
205             this.attr(input, 'curr_val', input.value);
206         }
207 
208         this.show();
209     },
210     onMouseover: function () {
211         var _this = this, icls = this.itemCls, acls = this.activeCls;
212         this.on(this.container, 'mouseover', function (e) {
213             var target = e.target || e.srcElement;
214             if (target.className == icls) {
215                 if (_this.active) {
216                     _this.active.className = icls;
217                 }
218                 target.className = acls;
219                 _this.active = target;
220             }
221         });
222     },
223     onMousedown: function () {
224         var _this = this;
225         this.on(this.container, 'mousedown', function (e) {
226             var target = e.target || e.srcElement;
227             _this.input.value = target.innerHTML;
228             _this.hide();
229         });
230     }
231 }    

画面上是这样调用的

 1 <!DOCTYPE HTML>
 2 <html>
 3 <head>
 4     <meta charset="utf-8">
 5     <title></title>
 6     <style type="text/css">
 7         body
 8         {
 9             margin: 0;
10             padding: 0;
11         }
12         input
13         {
14             width: 200px;
15         }
16         .suggest-container
17         {
18             border: 1px solid #C1C1C1;
19             visibility: hidden;
20             background-color: White;
21             z-index: 9999;
22         }
23         .suggest-item
24         {
25             padding: 3px 2px;
26         }
27         .suggest-active
28         {
29             background: #33CCFF;
30             color: white;
31             padding: 3px 2px;
32         }
33     </style>
34     <script src="../Scripts/jquery-1.4.1.js" type="text/javascript"></script>
35     <script src="../Scripts/autoComplateTool.js" type="text/javascript"></script>
36     <script type="text/javascript">
37 
38         $(document).ready(function () {
39             $("#guitai").focus(function () {
40                 var aToStr = $("#txtea_L").val();
41                 aToStr = $.trim(aToStr);
42                 var data = eval("(" + aToStr + ")");
43                 var arrSource = [];
44 
45                 for (var i = 0; i < data.length; i++) {
46                     arrSource.push(data[i].E);
47                 }
48 
49                 var sinaSuggest = new InputSuggest({
50                      300,
51                     opacity: 0.8,
52                     input: document.getElementById('guitai'),
53                     data: arrSource
54                     //['sina.cn', 'sina.com', 'vip.sina.com.cn', '2008.sina.com', '263.sina.com']
55                 });
56             });
57         });
58     </script>
59 </head>
60 <body>
61     <div style=" 400px; margin: 30px auto; text-align: center;">
62         <label>
63             柜台</label>
64         <input type="text" id="guitai" />
65         <br />
66         <br />
67     </div>
68     <div>
69         <textarea id="txtea_L" style=" 1550px; height: 100px;">
70            [ { 'A': 'DEP00000', 'B': '直营专柜', 'C': 'DEP0000XXXX','D': '直属', 'E': 'DEPFFFF',
71             'F': '上海地区','CounterKey': '000101', 'CounterName': '上海巴春五角场' },
72             {'A':'R1','B':'华东大区','C':'1010','D':'福建分公司','E':'DEPGFF','F':'赵子龙',
73              'G':'1010500007841','H':'XXXX化妆品店'} ]
74            </textarea>
75     </div>
76 </body>
77 </html>

完结撒花! Nice.

原文地址:https://www.cnblogs.com/mjxxsc/p/4588935.html