您的位置:首页 > 编程语言 > PHP开发

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

2007-11-09 15:39 806 查看
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.onchange=function(){
pointer.submits();
}
selectobj.ondblclick=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 onload="">

<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"> </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 即可。若有错,按我说的自己找找,别乱叫,最烦这种人!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: