个人认为是比较完整的自动完成插件(jquery)

最近项目需要,要一个带下拉,又可以自己填写的插件,在网上找了很多,都不太符合使用需求,所以自己学着做了一个,对比了很多自动完成,个人感觉这个算是功能上比较完整的了吧,废话不多说,上代码,供大家参考一下

callback方法可带一个参数,该参数反回了input的dom对象,注意,是dom对象,不是jquery对象

20150129:修改->
1.css中限制了下拉选框的高度,显示纵向滚动条
2.修复了拉下选框的滚动条焦点与IE的兼容性问题(针对以前用户在CSS中自行限制高度并设置滚动条的情况)

js:

  1 (function ($) {
  2     $.fn.myautocomplete = function (options, callback) {
  3         $.each(this, function (index, component) {
  4             var defaultVal = {
  5                 source: null,
  6                 ajax: null
  7             };
  8             var params = $.extend(defaultVal, options)
  9             var dictionary = null;//备选集合
 10             var $popup = null;//备选列表对象
 11             var $input = null;
 12             var $popupDiv = null;//解决下IE中拉选单超高,用户鼠标点击滚动条时焦点错误
 13 
 14             init();
 15 
 16             $.fn.myautocomplete.destory = function () {
 17                 var $newInput = $input.clone();
 18                 var $father = $input.parent();
 19                 $father.find("*").remove();
 20                 $father.append($newInput);
 21 
 22             }
 23 
 24             function init() {
 25                 initDictionary(); initInput(); deleteUselessObj(); initDropdownBtn(); initPopup();
 26             }
 27 
 28             function initDictionary() {
 29                 if (params.source && params.source instanceof Array)
 30                     dictionary = params.source;
 31                 else {
 32                     if (params.ajax) {
 33                         $.post(params.ajax, {}, function (data) {
 34                             var json = eval(data);
 35                             if (json instanceof Array)
 36                                 dictionary = json;
 37                         })
 38                     }
 39                 }
 40             }
 41 
 42             function initInput() {
 43                 $input = $(component);//input的jquery对象
 44                 $input.timer = null;
 45                 $input.oldValue = $input.val();
 46                 $input.keydown(function (event) { keydown(event) });
 47                 $input.focus(function () {
 48                     //设置每间隔200ms,检查值是否变化
 49                     $input.focusValue = $input.val();
 50                     if (!$input.timer)
 51                         $input.timer = setInterval(function () {
 52                             if ($input.val() != $input.oldValue) {
 53                                 $input.oldValue = $input.val();
 54                                 setPopup($input.val(), false);
 55                             }
 56                         }, 200)
 57                 })
 58 
 59                 $input.blur(function () {
 60                     setTimeout(function () {
 61                         if ($input.timer) {
 62                             clearInterval($input.timer);
 63                             $input.timer = null;
 64                         }
 65                         if (!isMyAutoCompleteIsOnFocus()) {
 66                             $popup.close();
 67                         }
 68                         if (callback && !isMyAutoCompleteIsOnFocus() && $input.focusValue != $input.val()) {
 69                             $input.focusValue = $input.val();
 70                             callback($input.get(0));
 71                         }
 72                     })
 73                 })
 74             }//initInput结束
 75 
 76             function deleteUselessObj() {
 77                 $input.parent().find("*").each(function (i, n) {
 78                     if (n != $input.get(0))
 79                         $(n).remove();
 80                 });
 81             }
 82 
 83             function initDropdownBtn() {
 84                 $dropdownBtn = $("<a>").attr("href", "javascript:;").attr("class", "dropdownBtn");//兼容ie7,8
 85                 $dropdownImg = $("<div class='dropdownImg'>");
 86                 $dropdownBtn.append($dropdownImg);
 87                 $dropdownBtn.insertAfter($input);
 88                 $dropdownBtn.click(function () {
 89                     $input.focusValue = $input.val();
 90                     if ($popup.visible)
 91                         $popup.close();
 92                     else {
 93                         setPopup('', true);
 94                     }
 95                 })
 96                 $dropdownBtn.blur(function () {
 97                     setTimeout(function () {
 98                         if (!isMyAutoCompleteIsOnFocus()) {
 99                             $popup.close();
100                         }
101                     });
102                 });
103                 $dropdownImg.blur(function () { $dropdownBtn.blur(); });//IE兼容性
104                 $dropdownBtn.keydown(function (event) { keydown(event); });
105             }
106 
107             function initPopup() {
108                 if ($input.parent() && $input.parent().find("ul").size() > 0)
109                     $input.parent().find("ul").remove();
110                 $popupDiv = $("<div class='popupDiv'></div>")
111                 $popup = $("<ul class='popup'>");
112                 $popupDiv.insertAfter($input);
113                 $popupDiv.append($popup);
114                 $popup.listSize = 0;
115                 $popup.hoverIndex = -1;
116                 $popupDiv.hide();
117                 $popup.visible = false;
118                 $popupDiv.css("top", $input.outerHeight()).css("left", "0");//left("0")兼容ie7
119                 $popup.close = function () {
120                     if ($popup.visible) {
121                         $input.parents().unbind("keydown", unbindBodyScroll);
122                         this.listSize = 0;
123                         this.hoverIndex = -1;
124                         $popup.html("");
125                         $popupDiv.hide();
126                         $popup.visible = false;
127                         if (callback && !isMyAutoCompleteIsOnFocus() && $input.focusValue != $input.val()) {
128                             $input.focusValue = $input.val();
129                             callback($input.get(0));
130                         }
131                     }
132                 }
133                 $popup.open = function () {
134                     $input.parents().bind("keydown", unbindBodyScroll);
135                     $popupDiv.show();
136                     $popup.visible = true;
137                 }
138                 $popupDiv.keydown(function (event) { if (!isPopupItemOnFocus() && document.activeElement != $input.get(0)) keydown(event) });
139                 $popup.keydown(function (event) { keydown(event) });
140                 $popupDiv.blur(function () {
141                     if (!isMyAutoCompleteIsOnFocus())
142                         $popup.close();
143                 })
144             }//initPopup结束
145             //设置下拉框内容
146             function setPopup(val, showPopupIfValIsNull) {
147                 $popup.html("");
148                 if (val || (!val && showPopupIfValIsNull)) {//判断是否满足显示被选框的条件
149                     var Reg = RegExp("^" + val)
150                     if (dictionary) {
151                         $(dictionary).each(function (i, n) {
152                             if (Reg.exec(n)) {
153                                 //匹配,添加下拉列表
154                                 var li = $("<li>");
155                                 var a = $("<a>")
156                                 a.text(n);
157                                 a.attr("href", "javascript:;");
158                                 a.click(function () {
159                                     $input.val(n);
160                                     $input.oldValue = n;
161                                     $input.focus();
162                                     $popup.close();
163                                     if (callback)
164                                         callback($input.get(0));
165                                 });
166                                 a.focus(function () {
167                                     a.addClass("hover");
168                                 });
169                                 a.blur(function () {
170                                     a.removeClass("hover");
171                                     setTimeout(function () {
172                                         if (!isMyAutoCompleteIsOnFocus())
173                                             $popup.close();
174                                     })
175                                 });
176                                 li.append(a);
177                                 $popup.append(li);
178                             }
179                         });//遍历数组进行匹配
180                         $popup.listSize = $popup.find("li").size();
181                         if ($popup.listSize > 0) {
182                             $popup.open();
183                         }
184                         else {
185                             $popup.close();
186                         }
187 
188                     }
189                 }
190                 else {
191                     if ($popup.visible)
192                         $popup.close();
193                 }
194             }
195             //按键事件
196             function keydown(event) {
197                 if ($popup.visible) {
198                     switch (event.keyCode) {
199                         case 13: {
200                             //按回车键
201                             if ($popup.hoverIndex != -1) {
202                                 $popup.find("a:eq(" + $popup.hoverIndex + ")").click();
203                             }
204                             break;
205                         }
206                         case 38: {
207                             //按↑键
208                             $popup.hoverIndex--;
209                             if ($popup.hoverIndex < -1)
210                                 $popup.hoverIndex = $popup.listSize - 1;
211                             $popup.find("a").removeClass("hover");
212                             if ($popup.hoverIndex != -1) {
213                                 $popup.find("a:eq(" + $popup.hoverIndex + ")").focus();
214                             }
215                             else
216                                 $input.focus();
217                             break;
218                         }
219                         case 40: {
220                             //按↓键
221                             $popup.hoverIndex++;
222                             if ($popup.hoverIndex > $popup.listSize - 1)
223                                 $popup.hoverIndex = -1;
224                             $popup.find("a").removeClass("hover");
225                             if ($popup.hoverIndex != -1) {
226                                 $popup.find("a:eq(" + $popup.hoverIndex + ")").focus();
227                             }
228                             else
229                                 $input.focus();
230                             break;
231                         }
232                     }
233                 }
234             }
235             //解除键盘的↑和↓键导致input父元素们的滚动条滚动
236             function unbindBodyScroll(event) {
237                 event = event ? event : window.event;
238                 if (event.keyCode == 38 || event.keyCode == 40) return false;
239             }
240 
241             function isMyAutoCompleteIsOnFocus() {
242                 return document.activeElement == $input.get(0) || isPopupItemOnFocus() || document.activeElement == $popupDiv.get(0);
243             }
244 
245             function isPopupItemOnFocus() {
246                 return document.activeElement.parentElement.parentElement == $popup.get(0);
247             }
248         })
249     }
250 })(jQuery);


css:(注意background-image在实际应用时的url地址)

 

 1 .autoComplete {
 2     position: relative;
 3     zoom: 1; /*ie7兼容*/
 4 }
 5 
 6     .autoComplete:after { /*ie8及更早的版本需要声明<!DOCTYPE html>*/
 7         clear: both;
 8         content: "";
 9         display: block;
10         visibility: hidden;
11         height: 0;
12     }
13 
14     .autoComplete input {
15         width: 200px;
16         height: 22px;
17         margin: 0;
18         padding: 0;
19         line-height: 22px;
20         display: block;
21         float: left;
22     }
23 
24         .autoComplete input::-ms-clear {
25             display: none;
26         }
27 
28     .autoComplete .dropdownBtn {
29         cursor: default;
30         margin-left: -14px;
31         float: left;
32         margin-left: -16px;
33     }
34 
35 /*ie7,ie8样式兼容*/
36 * + .autoComplete .dropdownBtn {
37     margin-left: -16px;
38 }
39 
40 .autoComplete .dropdownBtn .dropdownImg {
41     height: 23px;
42     width: 15px;
43     background-image: url(../img/dropdown.png);
44     background-size: 100%;
45 }
46 
47 .autoComplete .popupDiv {
48     z-index: 9999999999999;
49     padding: 0px;
50     margin: 0px;
51     position: absolute;
52 }
53 
54 .autoComplete .popup {
55     padding: 0px;
56     margin: 0px;
57     min-width: 200px;
58     border: 1px #333 solid;
59     background: white;
60     overflow-y: auto;
61     max-height: 190px;
62 }
63 
64 
65     .autoComplete .popup li {
66         list-style: none;
67     }
68 
69         .autoComplete .popup li a {
70             display: block;
71             color: #000;
72             text-decoration: none;
73             padding: 1px 0 1px 5px;
74             cursor: default;
75             _width: 97%;
76         }
77 
78             .autoComplete .popup li a:hover, .autoComplete .popup .hover {
79                 color: #000;
80                 background: #ccc;
81                 border: none;
82             }

 

还有一个图片,不传了,在压缩包里面都有.完整的例子也有

http://pan.baidu.com/s/1dDvS4Id

posted on 2015-01-21 10:47  没糖的咖啡  阅读(237)  评论(0编辑  收藏  举报

导航