仿GOOGLE下拉提示框(javascript)

调用:
后台数据以 [['关键字符','估计数量'], ['关键字符','估计数量'], ...] 格式输出。
页面onload后调用(因为有body.appendChild方法)
 var mySuggest = new hansir.TextSuggest(); mySuggest.add_suggest(inp, url, method, defer, defer2);
除了前两项必填,后三项都是可选的
inp :输入框ID名。
url :ajax请求的后台服务器页面地址。
method :发送方试 get或post,默认post。
defer :按键计时,即用户输入字符多久后请求服务器,默认不计时,用户输入字符后立即发送。
defer2 :服务器返回结果计时,即服务器发送请求后多长时间没有返回数据,列表自动隐藏,默认200ms。

 

code:

String. prototype.ltrim = function(){
return this. replace(/^/s*(.+?)$/, '$1');
}
//这里引用prototype的五个方法
function $(){ return document.getElementById( arguments[0]);}
Object.extend = function(destination, source){
for(property in source) destination[property] = source[property];
return destination;
}
function $A(iterable) {
var results = [];
for ( var i = 0; i < iterable. length; i++)results. push(iterable[i]);
return results;
}
Function. prototype.bindAsEventListener = function(object) {
var __method = this;
return function( event) {
return __method. call(object, event || window. event);
}
}
Function. prototype.bind = function() {
var __method = this, args = $A( arguments), object = args. shift();
return function() {
return __method. apply(object, args. concat($A( arguments)));
}
}
var hansir = {
url: 'http://www.hansir.cn'
}
hansir.AjAx = function(){ this.initialize. apply( this, arguments);}
hansir.AjAx. prototype = {
initialize: function( complete, method, url){
this. complete = complete;
this. method      = method || 'post';
this.url      = url;
if ( this. method == 'get') this.url += ( this.url. match(//?/) ? '&' : '?');
},
xmlHttp: function(){
var xmlHttp;
if( window.XMLHttpRequest) xmlHttp = new XMLHttpRequest();
else if( window. ActiveXObject)
try{
xmlHttp = new ActiveXObject( 'Msxml2.XMLHTTP');
} catch(errr){
xmlHttp = new ActiveXObject( 'Microsoft.XMLHTTP');
}
return xmlHttp;
},
request: function(parameters){
var xmlHttp = this.xmlHttp();
var send_val = null;
this. method== 'get' ? this.url += parameters : send_val = parameters;
xmlHttp. open( this. method, this.url, true);
xmlHttp.setRequestHeader( 'Content-type', 'application/x-www-form-urlencoded; charset=utf-8');
xmlHttp.onreadystatechange = this.ready_handler.bind( this, xmlHttp);
xmlHttp.send(send_val);
},
ready_handler: function(xmlHttp){
if(xmlHttp. readyState == 4){
if( this.success(xmlHttp)){
this. complete.load_data(xmlHttp);
}
}
},
success: function(xmlHttp){ return xmlHttp. status == 0 || xmlHttp. status >= 200 && xmlHttp. status < 300}
}
hansir.TextSuggest = function(){ this.initialize. apply( this, arguments);}
hansir.TextSuggest. prototype = {
initialize: function(){},
add_suggest: function(inp, url, method, defer, defer2){
var inp = $(inp);
inp.defer = defer || null;
inp.defer2 = defer2 || 200;
var sw = inp. offsetWidth, sh = inp. offsetHeight;
inp.suggest_list = this.create_list(sw, sh);
inp.suggest_list.par = inp;
inp.xmlHttp = new hansir.AjAx(inp.suggest_list, method, url);
Object.extend(inp, {
requesting : false,
last_result : true,
previous_value : null,
last_value : null,
kt : null,
rt : null,
load_event: function(){
if( this.addEventListener){
this.addEventListener( 'input', this.keyup_handler.bindAsEventListener( this), false);
} else if( this.attachEvent){
this.attachEvent( 'onkeyup', this.keyup_handler.bindAsEventListener( this));
}
},
keyup_handler: function(e){
var intKey;
window. event ? intKey = event. keyCode : intKey = e. which;
if(intKey == 38 || intKey == 40 || intKey == 13 || intKey == 37) return;
if( this.requesting) return;
var val = this. value.ltrim();
this.last_value = val;
if(val == this.previous_value) return;
if(val== ''){
this.previous_value = '';
this.last_value= '';
this.suggest_list. hidden();
this.suggest_list.clear_data();
return;
}
if( new RegExp( '^'+ this.last_result, 'i'). test(val)) return;
this.last_result = true;
this.previous_value = val;
if( this.kt) clearTimeout( this.kt);
this.defer? this.kt = setTimeout( this.send_request.bind( this), this.defer): this.send_request();
},
onblur: function(){
setTimeout( this.suggest_list. hidden.bind( this.suggest_list), 100);
},
onkeydown: function(e){ // 上下、回车键事件
if(! this.suggest_list.rows. length) return;
var intKey;
window. event ? intKey = event. keyCode : intKey = e. which;
switch(intKey){
case 38:
if( this.suggest_list. style. visibility== 'hidden'){
this.suggest_list.visible();
return;
}
var val = this.suggest_list.select_index(1);
val? this. value=val : this. value = this.last_value;
break;
case  40:
if( this.suggest_list. style. visibility== 'hidden'){
this.suggest_list.visible();
return;
}
var val= this.suggest_list.select_index(0);
val? this. value=val : this. value = this.last_value;
break;
case 13:
if( this.suggest_list.cur_tr!=-1){
this.suggest_list. hidden();
break;
}
case 39:
this.suggest_list. hidden();
this.keyup_handler( 'o');
}
},
send_request: function(){ // 请求数据
this.requesting = true;
var val = this. value;
var parameters = 'keyword=' + val.ltrim();
this.xmlHttp.request(parameters);
this.start_hidden_time();
},
start_hidden_time: function(){
if( this.rt) clearTimeout( this.rt);
this.rt = setTimeout( this.list_hidden.bind( this), this.defer2);
},
list_hidden: function(){
if( this.requesting) this.suggest_list. hidden();
}
});
inp.load_event();
},
create_list: function(w, h){ //创建列表
var table  = document.createElement( 'table');
table.cellSpacing = 0;
document.body.appendChild(table);
table. className = 'tab_suggest';
table. style. width = w + 'px';
table.parh = h-1;
Object.extend(table,{
cur_tr: -1,
set_pos: function(){ // 下垃框位置
var x=0, y=0, inp = this.par;
while(inp != null){ x += inp. offsetLeft; y += inp. offsetTop;inp = inp. offsetParent;}
inp = null;
table. style. left = x + 'px';
table. style. top = y+ this.parh+ 'px';
},
add: function(str, num){
var n=0;
this.rows. length ? n= this.rows. length : n = 0;
var tr = this.insertRow(n);
var th = document.createElement( 'th');
var td = document.createElement( 'td');
th. innerHTML = str, td. innerHTML = num;
tr.appendChild(th), tr.appendChild(td);
tr.num = this.rows. length-1;
tr.par = this;
tr. onmouseover = function(){
var par = this.par;
if(par.cur_tr!=-1 && par.cur_tr!= this.num){
par.rows[par.cur_tr]. className= '';
this. className = 'cur';
par.cur_tr = this.num;
} else{
this. className = 'cur';
par.cur_tr = this.num;
}
}
tr. onclick = function(){
var par = this.par.par;
par. value = this.cells[0]. innerHTML;
}
tr = null, th = null, td = null;
},
load_data: function(xmlHttp){ // 加载列表
var inp = this.par;
if(inp.previous_value != inp. value){
inp.requesting = false;
this.clear_data();
inp.keyup_handler( 'o');
return;
}
var arr = xmlHttp.responseText;
if(arr.ltrim() == 'null'){
inp.last_result = inp. value;
inp.requesting = false;
inp.suggest_list. hidden();
this.clear_data();
return;
}
var cur_data = eval(arr);
this.clear_data();
for( var i=0; i<cur_data. length; i++) this.add(cur_data[i][0],cur_data[i][1]);
this.cur_tr = -1;
this.visible();
inp.requesting = false;
},
clear_data: function(){ while( this.rows. length) this.deleteRow( this.rows[0])}, // 清空列表
select_index: function(n){ // 移动选项
if(n){
if( this.cur_tr==0){
this.rows[0]. className = '';
this.cur_tr = -1;
return false;
} else{
this.cur_tr==-1? this.cur_tr= this.rows. length : this.rows[ this.cur_tr]. className = '';
this.cur_tr = this.cur_tr-1;
this.rows[ this.cur_tr]. className = 'cur';
return this.rows[ this.cur_tr].cells[0]. innerHTML;
}
} else{
if( this.cur_tr == ( this.rows. length-1)){
this.rows[ this.cur_tr]. className= '';
this.cur_tr = -1;
return false;
} else{
if( this.cur_tr!=-1) this.rows[ this.cur_tr]. className = '';
this.cur_tr = this.cur_tr+1;
this.rows[ this.cur_tr]. className = 'cur';
return this.rows[ this.cur_tr].cells[0]. innerHTML;
}
}
},
hidden: function(){ this. style. visibility = 'hidden';}, // 隐
visible: function(){ this.set_pos(); this. style. visibility = 'visible';} // 显
});
return table;
}
}

你可能感兴趣的:(仿GOOGLE下拉提示框(javascript))