Jquery实现仿搜索引擎文本框自动补全插件功能很实用,使用也很简单,引入了插件之后写几行代码就可以实现,可以灵活设置 //width:下拉框的宽度,默认使用输入框宽度、用来ajax后台获取数据,返回的数据格式为data参数一样、数据格式{data: [{title:null,result:{}},{title:null,result:{}}]}url和data参数只有一个生效,data优先、 选中行后按回车或单击时回调的函数
效果如下:
在线演示和下载请查看:
http://www.jq-school.com/Detail.aspx?id=36
标签: jQuery
代码片段(1)
[代码] [JavaScript]代码
001 |
( function ($){ |
002 |
var bigAutocomplete = new function (){ |
003 |
this .currentInputText = null ; //目前获得光标的输入框(解决一个页面多个输入框绑定自动补全功能) |
004 |
this .functionalKeyArray = [9,20,13,16,17,18,91,92,93,45,36,33,34,35,37,39,112,113,114,115,116,117,118,119,120,121, //键盘上功能键键值数组 |
005 |
this .holdText = null ; //输入框中原始输入的内容 |
006 |
007 |
//初始化插入自动补全div,并在document注册mousedown,点击非div区域隐藏div |
008 |
this .init = function (){ |
009 |
$( "body" ).append( "<div id='bigAutocompleteContent' class='bigautocomplete-layout'></div>" ); |
010 |
$(document).bind( 'mousedown' , function (event){ |
011 |
var $target = $(event.target); |
012 |
if ((!($target.parents().andSelf().is( '#bigAutocompleteContent' ))) && (!$target.is(bigAutocomplete.currentInputText))){ |
013 |
bigAutocomplete.hideAutocomplete(); |
014 |
} |
015 |
}) |
016 |
017 |
//鼠标悬停时选中当前行 |
018 |
$( "#bigAutocompleteContent" ).delegate( "tr" , "mouseover" , function () { |
019 |
$( "#bigAutocompleteContent tr" ).removeClass( "ct" ); |
020 |
$( this ).addClass( "ct" ); |
021 |
}).delegate( "tr" , "mouseout" , function () { |
022 |
$( "#bigAutocompleteContent tr" ).removeClass( "ct" ); |
023 |
}); |
024 |
025 |
026 |
//单击选中行后,选中行内容设置到输入框中,并执行callback函数 |
027 |
$( "#bigAutocompleteContent" ).delegate( "tr" , "click" , function () { |
028 |
bigAutocomplete.currentInputText.val( $( this ).find( "div:last" ).html()); |
029 |
var callback_ = bigAutocomplete.currentInputText.data( "config" ).callback; |
030 |
if ($( "#bigAutocompleteContent" ).css( "display" ) != "none" && callback_ && $.isFunction(callback_)){ |
031 |
callback_($( this ).data( "jsonData" )); |
032 |
033 |
} |
034 |
bigAutocomplete.hideAutocomplete(); |
035 |
}) |
036 |
037 |
} |
038 |
039 |
this .autocomplete = function (param){ |
040 |
041 |
if ($( "body" ).length > 0 && $( "#bigAutocompleteContent" ).length <= 0){ |
042 |
bigAutocomplete.init(); //初始化信息 |
043 |
} |
044 |
045 |
var $ this = $( this ); //为绑定自动补全功能的输入框jquery对象 |
046 |
047 |
var $bigAutocompleteContent = $( "#bigAutocompleteContent" ); |
048 |
049 |
this .config = { |
050 |
//width:下拉框的宽度,默认使用输入框宽度 |
051 |
width:$ this .outerWidth() - 2, |
052 |
//url:格式url:""用来ajax后台获取数据,返回的数据格式为data参数一样 |
053 |
url: null , |
054 |
/*data:格式{data:[{title:null,result:{}},{title:null,result:{}}]} |
055 |
url和data参数只有一个生效,data优先*/ |
056 |
data: null , |
057 |
//callback:选中行后按回车或单击时回调的函数 |
058 |
callback: null }; |
059 |
$.extend( this .config,param); |
060 |
061 |
$ this .data( "config" , this .config); |
062 |
063 |
//输入框keydown事件 |
064 |
$ this .keydown( function (event) { |
065 |
switch (event.keyCode) { |
066 |
case 40: //向下键 |
067 |
068 |
if ($bigAutocompleteContent.css( "display" ) == "none" ) return ; |
069 |
070 |
var $nextSiblingTr = $bigAutocompleteContent.find( ".ct" ); |
071 |
if ($nextSiblingTr.length <= 0){ //没有选中行时,选中第一行 |
072 |
$nextSiblingTr = $bigAutocompleteContent.find( "tr:first" ); |
073 |
} else { |
074 |
$nextSiblingTr = $nextSiblingTr.next(); |
075 |
} |
076 |
$bigAutocompleteContent.find( "tr" ).removeClass( "ct" ); |
077 |
078 |
if ($nextSiblingTr.length > 0){ //有下一行时(不是最后一行) |
079 |
$nextSiblingTr.addClass( "ct" ); //选中的行加背景 |
080 |
$ this .val($nextSiblingTr.find( "div:last" ).html()); //选中行内容设置到输入框中 |
081 |
082 |
//div滚动到选中的行,jquery-1.6.1 $nextSiblingTr.offset().top 有bug,数值有问题 |
083 |
$bigAutocompleteContent.scrollTop($nextSiblingTr[0].offsetTop - $bigAutocompleteContent.height() + $nextSiblingTr.height() ); |
084 |
085 |
} else { |
086 |
$ this .val(bigAutocomplete.holdText); //输入框显示用户原始输入的值 |
087 |
} |
088 |
089 |
090 |
break ; |
091 |
case 38: //向上键 |
092 |
if ($bigAutocompleteContent.css( "display" ) == "none" ) return ; |
093 |
094 |
var $previousSiblingTr = $bigAutocompleteContent.find( ".ct" ); |
095 |
if ($previousSiblingTr.length <= 0){ //没有选中行时,选中最后一行行 |
096 |
$previousSiblingTr = $bigAutocompleteContent.find( "tr:last" ); |
097 |
} else { |
098 |
$previousSiblingTr = $previousSiblingTr.prev(); |
099 |
} |
100 |
$bigAutocompleteContent.find( "tr" ).removeClass( "ct" ); |
101 |
102 |
if ($previousSiblingTr.length > 0){ //有上一行时(不是第一行) |
103 |
$previousSiblingTr.addClass( "ct" ); //选中的行加背景 |
104 |
$ this .val($previousSiblingTr.find( "div:last" ).html()); //选中行内容设置到输入框中 |
105 |
106 |
//div滚动到选中的行,jquery-1.6.1 $$previousSiblingTr.offset().top 有bug,数值有问题 |
107 |
$bigAutocompleteContent.scrollTop($previousSiblingTr[0].offsetTop - $bigAutocompleteContent.height() + $previousSiblingTr.height()); |
108 |
} else { |
109 |
$ this .val(bigAutocomplete.holdText); //输入框显示用户原始输入的值 |
110 |
} |
111 |
112 |
break ; |
113 |
case 27: //ESC键隐藏下拉框 |
114 |
115 |
bigAutocomplete.hideAutocomplete(); |
116 |
break ; |
117 |
} |
118 |
}); |
119 |
120 |
//输入框keyup事件 |
121 |
$ this .keyup( function (event) { |
122 |
var k = event.keyCode; |
123 |
var ctrl = event.ctrlKey; |
124 |
var isFunctionalKey = false ; //按下的键是否是功能键 |
125 |
for ( var i=0;i<bigAutocomplete.functionalKeyArray.length;i++){ |
126 |
if (k == bigAutocomplete.functionalKeyArray[i]){ |
127 |
isFunctionalKey = true ; |
128 |
break ; |
129 |
} |
130 |
} |
131 |
//k键值不是功能键或是ctrl+c、ctrl+x时才触发自动补全功能 |
132 |
if (!isFunctionalKey && (!ctrl || (ctrl && k == 67) || (ctrl && k == 88)) ){ |
133 |
var config = $ this .data( "config" ); |
134 |
135 |
var offset = $ this .offset(); |
136 |
$bigAutocompleteContent.width(config.width); |
137 |
var h = $ this .outerHeight() - 1; |
138 |
$bigAutocompleteContent.css({ "top" :offset.top + h, "left" :offset.left}); |
139 |
140 |
var data = config.data; |
141 |
var url = config.url; |
142 |
var keyword_ = $.trim($ this .val()); |
143 |
if (keyword_ == null || keyword_ == "" ){ |
144 |
bigAutocomplete.hideAutocomplete(); |
145 |
return ; |
146 |
} |
147 |
if (data != null && $.isArray(data) ){ |
148 |
var data_ = new Array(); |
149 |
for ( var i=0;i<data.length;i++){ |
150 |
if (data[i].title.indexOf(keyword_) > -1){ |
151 |
data_.push(data[i]); |
152 |
} |
153 |
} |
154 |
155 |
makeContAndShow(data_); |
156 |
} else if (url != null && url != "" ){ //ajax请求数据 |
157 |
$.post(url,{keyword:keyword_}, function (result){ |
158 |
makeContAndShow(result.data) |
159 |
}, "json" ) |
160 |
} |
161 |
162 |
163 |
bigAutocomplete.holdText = $ this .val(); |
164 |
} |
165 |
//回车键 |
166 |
if (k == 13){ |
167 |
var callback_ = $ this .data( "config" ).callback; |
168 |
if ($bigAutocompleteContent.css( "display" ) != "none" ){ |
169 |
if (callback_ && $.isFunction(callback_)){ |
170 |
callback_($bigAutocompleteContent.find( ".ct" ).data( "jsonData" )); |
171 |
} |
172 |
$bigAutocompleteContent.hide(); |
173 |
} |
174 |
} |
175 |
176 |
}); |
177 |
178 |
179 |
//组装下拉框html内容并显示 |
180 |
function makeContAndShow(data_){ |
181 |
if (data_ == null || data_.length <=0 ){ |
182 |
return ; |
183 |
} |
184 |
185 |
var cont = "<table><tbody>" ; |
186 |
for ( var i=0;i<data_.length;i++){ |
187 |
cont += "<tr><td><div>" + data_[i].title + "</div></td></tr>" |
188 |
} |
189 |
cont += "</tbody></table>" ; |
190 |
$bigAutocompleteContent.html(cont); |
191 |
$bigAutocompleteContent.show(); |
192 |
193 |
//每行tr绑定数据,返回给回调函数 |
194 |
$bigAutocompleteContent.find( "tr" ).each( function (index){ |
195 |
$( this ).data( "jsonData" ,data_[index]); |
196 |
}) |
197 |
} |
198 |
199 |
200 |
//输入框focus事件 |
201 |
$ this .focus( function (){ |
202 |
bigAutocomplete.currentInputText = $ this ; |
203 |
}); |
204 |
205 |
} |
206 |
//隐藏下拉框 |
207 |
this .hideAutocomplete = function (){ |
208 |
var $bigAutocompleteContent = $( "#bigAutocompleteContent" ); |
209 |
if ($bigAutocompleteContent.css( "display" ) != "none" ){ |
210 |
$bigAutocompleteContent.find( "tr" ).removeClass( "ct" ); |
211 |
$bigAutocompleteContent.hide(); |
212 |
} |
213 |
} |
214 |
215 |
}; |
216 |
217 |
218 |
$.fn.bigAutocomplete = bigAutocomplete.autocomplete; |
219 |
220 |
})(jQuery) |
发表回复