php+ajax 实现仿google suggest效果的autocomplete功能代码

14 篇文章 0 订阅
10 篇文章 0 订阅

 

 

php +ajax 实现仿google suggest效果的autocomplete功能代码

本文是我在项目过程中用到的一个autocomplete功能,纯javascript实现,没有用到相关框架及类库。效果不错,特粘贴出来,希望高手指正,并完善。实现了autocomplete 以及 键盘up和down的功能。缺点:如果数据量大,则运行较慢,有待改进。说明:其中autocomplete.php文件为连接后台mysql数据库并获取xml格式数据的,如要运行,需自行修改数据库相关设置。此处数据库名为inv,数据表为pt_part,相关字段有pt_part,pt_desc...如需拷贝,需自行建立数据库及表,并在autocomplete.php文件中修改相关设置即可。经测试,效果不错哦。

1.suggest.html文件:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="
http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type"  content="text/html; charset=big5" />
<meta name="keywords"    content="AJAX Asynchronous JavaScript + XML Asynchronous Javascript And XML DOM Document Object Mode CSS CSS2 CSS3" />
<meta name="description"   content="AJAX Asynchronous JavaScript + XML Asynchronous Javascript And XML DOM Document Object Mode CSS CSS2 CSS3" />
<meta name="Author"        content="Audi" />
<meta name="Author"    content="
http://audi.tw" />
<meta http-equiv="Pragma"   content="no-cache" />
<meta http-equiv="Expires"   content="-1" />
<meta http-equiv="Cache-Control"  content="no-cache" />
<title>AJAX </title>
<style rel="stylesheet" type="text/css">
._sgClass{background:white;}
.td_over{background-color:#3366cc;}
.td_out{background-color:white;}
</style>
<script type="text/javascript" >
     autoComplete.js   //

autoComplete=function(fID){//create autocomplete object
 this.id=document.getElementById(fID);
 if (!this.id) return false;
 this.div      ='_sg';
 this.className  ='_sgClass';
 this.suggest  ='_qg';
 this.marginTop  =12;
 this.marginLeft  =12;
 this.divWidth  ='372px';
 this.selectHeight =6;
 this.xmlHttp  =this.createXHR();
 var pointer = this;
 this.id.onkeyup = function(e){ return pointer.onKeyUp(e); }
}

autoComplete.prototype.onKeyUp=function(e){
 var key = (window.event) ? window.event.keyCode : e.which;

 switch(key){
  case 13: //return
   break;
  case 8:  //backspace
   break;
  case 9:  //tab
   break; //do nothing
  case 27: //esc
   this.id.value='';
   break;
  case 38: //up
   this.moveSelectionUp();
   break;
  case 40: //down
      this.moveSelectionDown();
   break;
  default:
   this.getRequest();
 }
}

 autoComplete.prototype.moveSelectionUp=function() {//key up
      var index = document.getElementById(this.suggest);
        if (index.selectedIndex > 0){
   index.selectedIndex --;
      this.id.value =index.options[index.selectedIndex].value;
   }
   else if(index.selectedIndex == 0){
   index.selectedIndex = -1;
   this.id.value = value_1;//走到最顶端将值赋给输入的值
   this.id.focus();//输入框得到焦点
   }else if(index.selectedIndex == -1){
   index.selectedIndex = index.options.length-1;
   }
   }
  
autoComplete.prototype.moveSelectionDown=function() {//key down
       var index = document.getElementById(this.suggest);
   if (index.selectedIndex < index.options.length-1){
   index.selectedIndex ++;
   this.id.value =index.options[index.selectedIndex].value;
   }
   else {
    index.selectedIndex = -1;
   this.id.value = value_1;//走到最底端将值赋给输入的值
   this.id.focus();//输入框得到焦点
   }
  
   }

autoComplete.prototype.getRequest=function(){
 var url='autoComplete.php?s='+this.id.value+'&ts='+new Date().getTime();
 this.sendRequest(url);
 value_1 = this.id.value;//get the value
}

autoComplete.prototype.createLayer=function(){

 var divName=this.div;
 var sName=this.suggest;
 var obj=this.id;
 var body=document.getElementsByTagName("body")[0];

 //create layer
 if (document.getElementById(divName)==null){
  var div=document.createElement('div');
  div.setAttribute('id',divName);
  div.style.position='absolute';
  div.style.width=obj.offsetWidth+'px';

  var pos=this.getPos(this.id);
  div.style.left=pos.x+'px';
  div.style.top=(pos.y+obj.offsetHeight)+'px';

  body.appendChild(div);
 }
}

autoComplete.prototype.getPos=function(d){
 var cx=0,cy=0,obj;
 obj=d;

 if (obj.offsetParent){
  while (obj.offsetParent){
   cx += obj.offsetLeft;
   obj = obj.offsetParent;
  }
 }else if(obj.x){
  cx+=obj.x;
 }

 obj=d;

 if (obj.offsetParent){
  while (obj.offsetParent){
   cy += obj.offsetTop;
   obj = obj.offsetParent;
  }
 }else if(obj.y){
  cy+=obj.y;

 }

 //IE 干 body  margin
 var b=navigator.userAgent;
 var ie=(b.indexOf('MSIE')!=-1);
 var opera=(b.indexOf('Opera')!=-1);
 var mozilla=(b.indexOf('Mozilla')!=-1);
 if (ie){
  return {x:cx+this.marginLeft, y:cy+this.marginTop}
 }else{
  return {x:cx, y:cy}
 }
}

autoComplete.prototype.showSuggest=function(va){
 var obj=document.getElementById(this.div);

 var selectobj=document.createElement("select");
 for (var i=0;i<va.length;i++){
  var op=document.createElement("option");
  var sText=document.createTextNode(va[i][1])
  op.appendChild(sText);
  op.setAttribute('value',va[i][1]);
  selectobj.appendChild(op);
 }

 selectobj.setAttribute('id',this.suggest);
 selectobj.setAttribute('name',this.suggest);
 selectobj.setAttribute('size',this.selectHeight);
 selectobj.style.width=this.divWidth;
 
 //耞琌竒Τ某虫
 if (document.getElementById(this.suggest)){
  obj.replaceChild(selectobj,document.getElementById(this.suggest));
 }else{
  obj.appendChild(selectobj);
 }
    var pointer=this;
 selectobj.οnchange=function(){
  pointer.submits();
  }
 selectobj.οndblclick=function(){
  pointer.submits();
  }
}

autoComplete.prototype.submits=function(){
 var v=document.getElementById(this.suggest).value;
 this.id.value=v;
 var body=document.getElementsByTagName("body")[0];
 body.removeChild(document.getElementById(this.div));
}

autoComplete.prototype.createXHR=function(){
 var xmlHttp;
 if (window.XMLHttpRequest) {
  xmlHttp = new XMLHttpRequest();
 }else if (window.ActiveXObject) {
  xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
 }

 if (!xmlHttp) {
  alert('眤ㄏノ聅凝竟ぃや穿 XMLHTTP ン');
  return false;
 }else{
  return xmlHttp;
 }
}

autoComplete.prototype.sendRequest=function(url){
 var pointer=this;

 this.xmlHttp.open('GET',url,true);
 this.xmlHttp.onreadystatechange=function(){pointer.catchXML()};
 this.xmlHttp.send(null);
}

autoComplete.prototype.catchXML=function(){
 if (this.xmlHttp.readyState==4){
  xml=this.xmlHttp.responseXML;
  if (this.xmlHttp.status == 200) {
       this.createLayer();
       this.showSuggest(getNodeContent(xml));
  }else{
   alert(this.xmlHttp.status);
  }
 }
}

///      xml.js    /

// Array.indexOf( value, begin, strict ) - Return index of the first element that matches value
Array.prototype.indexOf = function( v, b, s ) {
 for( var i = +b || 0, l = this.length; i < l; i++ ) {
  if( this[i]===v || s && this[i]==v ){
   return i;
  }
  }
 return -1;
};

// Array.push() - Add an element to the end of an array, return the new length
if( typeof Array.prototype.push==='undefined' ) {
 Array.prototype.push = function() {
  for( var i = 0, b = this.length, a = arguments, l = a.length; i<l; i++ ) {
   this[b+i] = a[i];
  }
  return this.length;
 };
}

// Array.unique( strict ) - Remove duplicate values
Array.prototype.unique = function( b ) {
 var a = [], i, l = this.length;
 for( i=0; i<l; i++ ) {
  if( a.indexOf( this[i], 0, b ) < 0 ) { a.push( this[i] ); }
 }
 return a;
};

function getNodeContent(xmldoc,key,label) {
 
 var na=[],va=[],l;
 var outstr='';

 key=(typeof key=='undefined')?getNodeName(xmldoc,false):key;

 for (var i=0;i<xmldoc.getElementsByTagName(key).length;i++){
  var xml=xmldoc.getElementsByTagName(key)[i];
  na=getNodeName(xml,false); //ゲ惠琌斑,钡ㄓ笆,穦ㄌ弄

  for (var j=0;j<na.length;j++){
   var xmlk=xml.getElementsByTagName(na[j]);
   for (var k=0;k<xmlk.length;k++){
    l=Math.max(va.length,va.length-1);
    if(typeof label!='undefined'){
     if(typeof xmlk[k].getAttribute(label)!=null && typeof xmlk[k].getAttribute(label)!=''){
      va[l]=[xmlk[k].getAttribute(label),xmlk[k].childNodes[0].nodeValue];
     }else{
      va[l]=[na[j],xmlk[k].childNodes[0].nodeValue];
     }
    }else{
     va[l]=[na[j],xmlk[k].childNodes[0].nodeValue];
    }
    outstr+=va[l]+'/n';
   }
  }
 }

 return va
}

function getNodeName(xmldoc,duplicate){

 var d;
 var na=[];

 d=(typeof duplicate=='undefined')?true:duplicate;

 for (var i=0;i<xmldoc.childNodes.length;i++){
  if (xmldoc.childNodes[i].hasChildNodes()){
   na=na.concat(xmldoc.childNodes[i].tagName);
  }
 }

 na=(d)?na:na.unique();

 return na
}

</script>
</head>
<body οnlοad="">

<h3>AJAX </h3>
<form id="form1" name="form1" method="post" action="">
 <table width="100%" border="0" cellspacing="1" cellpadding="2">
  <tr>
   <td>
    part:<input name="searchStr" type="text" id="searchStr" style="width:360px;border:#000 1px solid;"  />
    <input type="submit" name="bt_submit" value="submit" />
   </td>
  </tr>
  <tr>
   <td align="left">&nbsp;</td>
  </tr>
 </table>
</form>
<script type="text/javascript">
 var xml_autoC = new autoComplete('searchStr','autoComplete.php');
</script>
</body>
</html>

2.autoComplete.php 文件(从后台mysql数据库中获取数据,生成XML格式输出)完整代码如下:

<?PHP
header('Content-Type: text/xml;
        charset=gb2312;
  Pragma: no-cache;
  Cache-Control: no-cache;');

$mysql_server_name = "localhost";
$mysql_username    = "root";
$mysql_password    = "831025";
$mysql_database    = "inv";

mysql_connect( $mysql_server_name, $mysql_username, $mysql_password )
 or die("database communication failed");
mysql_select_db($mysql_database);

$part = $_GET['s'];

$query = "SELECT pt_part,pt_desc FROM part WHERE pt_part LIKE '".trim($part)."%' ";
$result = mysql_query($query);

header("Content-Type:text/xml");
echo "<?xml version=/"1.0/" encoding=/"gb2312/"?>";
echo "<root>";

$rownumber = mysql_num_rows($result);
if( $rownumber > 0 )
{
 while( $row = mysql_fetch_array($result) )
 {
  echo "<name>". $row["pt_part"]." </name>";
 }
}
echo "</root>";
?>

完整拷贝代码,将两个文件置于c://appserv/www 目录下,修改数据库相关记录,访问 http://localhost/suggest.html 即可。若有错,按我说的自己找找,别乱叫,最烦这种人!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Lucene suggest实现代码可以分为以下几个部分: 1. 构建索引 Lucene suggest中的索引是使用Lucene库中的IndexWriter和Document对象来创建的。首先,需要创建一个IndexWriter对象,并指定索引的存储位置和一些基本配置。然后,需要遍历数据源中的每个文档,将其转换为Lucene的Document对象,并将其添加到IndexWriter中。在构建Document对象时,需要将文档中的每个单词分解为三元组,并将其添加到Document的一个或多个字段中。 2. 构建前缀数据结构 在索引构建完成后,需要构建一个前缀数据结构,用于搜索建议的查询。这个前缀数据结构是通过遍历索引中的所有文档和字段来创建的。对于每个字段,需要提取其中的所有三元组,并将它们添加到前缀数据结构中。这个前缀数据结构是一个基于Trie树的数据结构,可以有效地支持前缀匹配查询。 3. 提供搜索建议 在前缀数据结构构建完成后,就可以使用它来提供搜索建议了。对于每个用户查询,Lucene suggest会遍历前缀数据结构,查找所有以查询词为前缀的三元组,并将它们按照频率和相关性进行排序。然后,Lucene suggest会返回前N个排名最高的三元组,作为搜索建议的结果。 以上就是Lucene suggest的主要实现代码和流程。需要注意的是,这只是一个概述,具体的实现细节和代码会因应用场景和需求而有所不同。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值