NET+Ajax 实现站内搜索
近这几天开始研究Ajax ,发现它的功能很强大,所以自己就做了个练习,主要功能是实现仿 google的站点内搜索数据库中内容, 本人也是javascript 的初学者,所以代码还有很多BUG 希望各位高手能够给与指点,如果觉得还有点用的话就给加点分哈,另外,想说的就是本人极力支持开源希望能和有识之士共同交流,下面就是我的全部代码,在脚本部分我加了很多注释(因为代码比较长),所以还请大家耐心的看啊。。
代码部分:一。CSS部分
<style>
.spancss { BACKGROUND-COLOR: #d3d3d3 }
.search_suggest { BORDER-RIGHT: #a9a9a9 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: 0px solid; PADDING-LEFT: 0px; FONT-SIZE: x-small; PADDING-BOTTOM: 0px; MARGIN: 0px; BORDER-LEFT: #a9a9a9 1px solid; WIDTH: 155px; PADDING-TOP: 0px; BORDER-BOTTOM: #a9a9a9 1px solid; FONT-FAMILY: 宋体; POSITION: absolute; HEIGHT: 50px; BACKGROUND-COLOR: white }
.suggest_hidden { DISPLAY: none }
</style>
.spancss { BACKGROUND-COLOR: #d3d3d3 }
.search_suggest { BORDER-RIGHT: #a9a9a9 1px solid; PADDING-RIGHT: 0px; BORDER-TOP: 0px solid; PADDING-LEFT: 0px; FONT-SIZE: x-small; PADDING-BOTTOM: 0px; MARGIN: 0px; BORDER-LEFT: #a9a9a9 1px solid; WIDTH: 155px; PADDING-TOP: 0px; BORDER-BOTTOM: #a9a9a9 1px solid; FONT-FAMILY: 宋体; POSITION: absolute; HEIGHT: 50px; BACKGROUND-COLOR: white }
.suggest_hidden { DISPLAY: none }
</style>
二。Script脚本部分
<script>
var xmlhttprequest;
function getmessage(handler) //创建 xmlhttp对象
{
var xmlhttp;
try{
xmlhttp = new XMLHTTPRequest();
xmlhttp.onload = handler;
xmlhttp.onerror=handler;
return xmlhttp;
}
catch(e)
{
try{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange=handler;
return xmlhttp;
}
catch(e)
{
alert("not open object"+e.message);
return false;
}
}
}
var code=""; //文本框中的全部字符串
var str; //截取输入前的字符串
var len; //获取输入的字符串
var downcount =0; //记录向下键点击次数
var upcount = 0; //记录向上键点击次数
var ctrlcount = 0; //记录Ctrl键 点击次数
var zhcount = 0; //统计中文切换后 敲击的空格
function keyup() //键盘弹起事件时执行的方法,能够处理 英文,中文
{
var s=/^[\u4e00-\u9fa5]+$/; //创建 中文过滤器
str=event.srcElement.value.substring(0,code.length);
len = event.srcElement.value.substring(str.length); //通过截取获得刚输入的字符
if(event.keyCode>=65&&event.keyCode<=122) //判断输入的是否是字母
{
code = code+String.fromCharCode(event.keyCode); //将字 ASCII码转换成字符
sendpress(code); //向服务器发送 并处理返回结果
}
else if(len.match(s)) //获取中文字符
{
var value=len.replace(/[^\u4E00-\u9FA5]/g); //将输入的字符转换成汉字
code=code+value;
zhcount++; //切换输入法后输入空格的个数
sendpress(code); // 向服务器发送数据并返回结果
}
if(event.keyCode==17) //触发ctrl事件
{
ctrlcount=1; //设置CTRL的默认值
return;
}
if(event.keyCode==8) //触发回退事件
{
backpress(code);
return;
}
if(event.keyCode==32) //触发 空格 事件
{
spacepress(code);
return;
}
if(event.keyCode==38) //触发 向上键事件
{
uppress(downcount);
return;
}
if(event.keyCode==40) //触发 向下键事件
{
downpress(downcount);
return;
}
}
function divonblur() //触发此事件,使DIV失去焦点
{
var onblur_event=event.srcElement; //获得触发此事件的DIV
var onblur_parent=onblur_event.parentElement.parentElement; //获得其父级DIV
if(onblur_parent.tagName=="TR") //筛选出父级DIV
onblur_event.attributes["class"].value="suggest_hidden"; //隐藏
else
return;
}
function mouseover() //SPAN中悬停事件
{
var mouse_event=event.srcElement; //获取触发事件的 SPAN
var mouse_parent=mouse_event.parentElement; //获取其父级DIV
mouse_parent.attributes["class"].value="spancss"; //为其父级DIV添加背景CSS
document.getElementById("seach").innerText=mouse_event.innerText; //为文本框赋值
mouse_parent.parentElement.focus(); //获得焦点
return;
}
function mouseout() //SPAN中移开事件
{
var mouse_event=event.srcElement; //触发此事件的DIV
var mouse_parent=mouse_event.parentElement; //获得其父级DIV
mouse_parent.attributes["class"].value=""; //重置背景
return;
}
function uppress(upcode) //向上 键盘 事件
{
downcount--; //上移
var search =document.getElementById("seachlist"); //获得容器 DIV
var textvalue=document.getElementById("seach"); //
for(var j=search.children.length-1;j>=0;j--)
{
if(downcount==-1) //如果超出列表范围 从下方进入
{ downcount=search.children.length-1; //重新初始化 downcount
search.children[0].attributes["class"].value=""; //取消第一行DIV的背景色
}
else
search.children[j].attributes["class"].value=""; //重置CSS
if(downcount==j)
{
search.children[j].attributes["class"].value="spancss"; //设置DIV背景色
textvalue.innerText=search.children[j].children[0].innerText; //为文本框赋值
return;
}
}
}
function downpress(downcode) //按向下箭头触发的事件
{
var search =document.getElementById("seachlist"); //获得容器DIV
for(var num=0;num<search.children.length;num++) //遍历容器DIV
{
if(downcode==num) //判断当前位置
{
downcount++; //下移
search.children[num].attributes["class"].value="spancss"; //设置背景色
if(num==search.children.length-1) //判断是否到达底部 如到达底部对其进行截取空格
{
document.getElementById("seach").innerText=search.children[num].children[0].innerText.substring(0,search.children[num].children[0].innerText.length-1);
return;
}
else
{
document.getElementById("seach").innerText=search.children[num].children[0].innerText;
return;
}
}
else
{
search.children[num].attributes["class"].value=""; //重置当前背景色
}
}
downcount = 0; //位置指针指向容器 DIV的首行
}
function spacepress(spacecode) //按下空格时code 长度增加
{ if(zhcount==0)
{
if(ctrlcount==0) //判断输入法是否按 CTRl键
{
code=spacecode+" "; //当在文本框中输入空格时 总值迎加上空格值
sendpress(code);
}
else
{
ctrlcount=0; //恢复默认
}
}
else //如果切换输入法后输入
{
sendpress(spacecode);
zhcount=0;
}
}
function backpress(backcode) //按回退键时 发生的事件
{
var strcode = backcode.substring(backcode.substring(0,backcode.length-2).length);
//截取最后两位
if(strcode.match(/^[\u4e00-\u9fa5]+$/)) //判断截取后是否是中文
code= code.substring(0,code.length-2);
else if(strcode.match(/^[A-Za-z]+$/))
code = code.substring(0,code.length-1);//如不是则截取一位
else
code = code.substring(0,code.length-1); //其他情况也截取一位
if(code)
{
sendpress(code); //向服务器提交数据
}
}
function divcss() // 空数据时层的显示和隐藏
{
//判断SPAN中的内容
if(document.getElementById("seachlist").children[0].children[0].innerHTML!="")
{
document.getElementById("seachlist").attributes["class"].value="search_suggest";
}
else
{
document.getElementById("seachlist").attributes["class"].value="suggest_hidden";
//隐藏父级DIV
return;
}
}
function sendpress(sendcode) //向服务器发送 并接收 数据
{
var url="WebForm8.aspx?param=1";
xmlhttprequest=getmessage(showlist); //实例化 XMLHTTP 对象
xmlhttprequest.open("GET",url,true); //打开连接
xmlhttprequest.send(sendcode); //向服务器发送数据
}
function showlist() //onreadystatechange 事件执行的方法
{
if(xmlhttprequest.readyState==4||xmlhttprequest.readyState=="complete")
{
//判断状态
document.getElementById("seachlist").innerHTML=""; //向容器DIV添加元素
var httptext = xmlhttprequest.responseText; //获取服务器返回字符串
var strtext = httptext.substring(0,httptext.indexOf('<'));//获取服务器发送过来的文本
var arry = new Array();
arry = strtext.split(',');
for(var i=0;i<arry.length;i++) //对其进行遍历
{
var div = document.createElement("DIV"); //创建子DIV
div.id = i; //设定ID
div.onblur= divonblur; //添加失去焦点事件
div.innerHTML="<SPAN onmouseover='mouseover();' onmouseout='mouseout();'>"+arry[i]+"</SPAN></br>";
//创建SPAN添加到子容器DIV中
document.getElementById("seachlist").appendChild(div);
//将子容器挂载到父容器中
}
divcss(); //判断是否隐藏
}
}
</script>
var xmlhttprequest;
function getmessage(handler) //创建 xmlhttp对象
{
var xmlhttp;
try{
xmlhttp = new XMLHTTPRequest();
xmlhttp.onload = handler;
xmlhttp.onerror=handler;
return xmlhttp;
}
catch(e)
{
try{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
xmlhttp.onreadystatechange=handler;
return xmlhttp;
}
catch(e)
{
alert("not open object"+e.message);
return false;
}
}
}
var code=""; //文本框中的全部字符串
var str; //截取输入前的字符串
var len; //获取输入的字符串
var downcount =0; //记录向下键点击次数
var upcount = 0; //记录向上键点击次数
var ctrlcount = 0; //记录Ctrl键 点击次数
var zhcount = 0; //统计中文切换后 敲击的空格
function keyup() //键盘弹起事件时执行的方法,能够处理 英文,中文
{
var s=/^[\u4e00-\u9fa5]+$/; //创建 中文过滤器
str=event.srcElement.value.substring(0,code.length);
len = event.srcElement.value.substring(str.length); //通过截取获得刚输入的字符
if(event.keyCode>=65&&event.keyCode<=122) //判断输入的是否是字母
{
code = code+String.fromCharCode(event.keyCode); //将字 ASCII码转换成字符
sendpress(code); //向服务器发送 并处理返回结果
}
else if(len.match(s)) //获取中文字符
{
var value=len.replace(/[^\u4E00-\u9FA5]/g); //将输入的字符转换成汉字
code=code+value;
zhcount++; //切换输入法后输入空格的个数
sendpress(code); // 向服务器发送数据并返回结果
}
if(event.keyCode==17) //触发ctrl事件
{
ctrlcount=1; //设置CTRL的默认值
return;
}
if(event.keyCode==8) //触发回退事件
{
backpress(code);
return;
}
if(event.keyCode==32) //触发 空格 事件
{
spacepress(code);
return;
}
if(event.keyCode==38) //触发 向上键事件
{
uppress(downcount);
return;
}
if(event.keyCode==40) //触发 向下键事件
{
downpress(downcount);
return;
}
}
function divonblur() //触发此事件,使DIV失去焦点
{
var onblur_event=event.srcElement; //获得触发此事件的DIV
var onblur_parent=onblur_event.parentElement.parentElement; //获得其父级DIV
if(onblur_parent.tagName=="TR") //筛选出父级DIV
onblur_event.attributes["class"].value="suggest_hidden"; //隐藏
else
return;
}
function mouseover() //SPAN中悬停事件
{
var mouse_event=event.srcElement; //获取触发事件的 SPAN
var mouse_parent=mouse_event.parentElement; //获取其父级DIV
mouse_parent.attributes["class"].value="spancss"; //为其父级DIV添加背景CSS
document.getElementById("seach").innerText=mouse_event.innerText; //为文本框赋值
mouse_parent.parentElement.focus(); //获得焦点
return;
}
function mouseout() //SPAN中移开事件
{
var mouse_event=event.srcElement; //触发此事件的DIV
var mouse_parent=mouse_event.parentElement; //获得其父级DIV
mouse_parent.attributes["class"].value=""; //重置背景
return;
}
function uppress(upcode) //向上 键盘 事件
{
downcount--; //上移
var search =document.getElementById("seachlist"); //获得容器 DIV
var textvalue=document.getElementById("seach"); //
for(var j=search.children.length-1;j>=0;j--)
{
if(downcount==-1) //如果超出列表范围 从下方进入
{ downcount=search.children.length-1; //重新初始化 downcount
search.children[0].attributes["class"].value=""; //取消第一行DIV的背景色
}
else
search.children[j].attributes["class"].value=""; //重置CSS
if(downcount==j)
{
search.children[j].attributes["class"].value="spancss"; //设置DIV背景色
textvalue.innerText=search.children[j].children[0].innerText; //为文本框赋值
return;
}
}
}
function downpress(downcode) //按向下箭头触发的事件
{
var search =document.getElementById("seachlist"); //获得容器DIV
for(var num=0;num<search.children.length;num++) //遍历容器DIV
{
if(downcode==num) //判断当前位置
{
downcount++; //下移
search.children[num].attributes["class"].value="spancss"; //设置背景色
if(num==search.children.length-1) //判断是否到达底部 如到达底部对其进行截取空格
{
document.getElementById("seach").innerText=search.children[num].children[0].innerText.substring(0,search.children[num].children[0].innerText.length-1);
return;
}
else
{
document.getElementById("seach").innerText=search.children[num].children[0].innerText;
return;
}
}
else
{
search.children[num].attributes["class"].value=""; //重置当前背景色
}
}
downcount = 0; //位置指针指向容器 DIV的首行
}
function spacepress(spacecode) //按下空格时code 长度增加
{ if(zhcount==0)
{
if(ctrlcount==0) //判断输入法是否按 CTRl键
{
code=spacecode+" "; //当在文本框中输入空格时 总值迎加上空格值
sendpress(code);
}
else
{
ctrlcount=0; //恢复默认
}
}
else //如果切换输入法后输入
{
sendpress(spacecode);
zhcount=0;
}
}
function backpress(backcode) //按回退键时 发生的事件
{
var strcode = backcode.substring(backcode.substring(0,backcode.length-2).length);
//截取最后两位
if(strcode.match(/^[\u4e00-\u9fa5]+$/)) //判断截取后是否是中文
code= code.substring(0,code.length-2);
else if(strcode.match(/^[A-Za-z]+$/))
code = code.substring(0,code.length-1);//如不是则截取一位
else
code = code.substring(0,code.length-1); //其他情况也截取一位
if(code)
{
sendpress(code); //向服务器提交数据
}
}
function divcss() // 空数据时层的显示和隐藏
{
//判断SPAN中的内容
if(document.getElementById("seachlist").children[0].children[0].innerHTML!="")
{
document.getElementById("seachlist").attributes["class"].value="search_suggest";
}
else
{
document.getElementById("seachlist").attributes["class"].value="suggest_hidden";
//隐藏父级DIV
return;
}
}
function sendpress(sendcode) //向服务器发送 并接收 数据
{
var url="WebForm8.aspx?param=1";
xmlhttprequest=getmessage(showlist); //实例化 XMLHTTP 对象
xmlhttprequest.open("GET",url,true); //打开连接
xmlhttprequest.send(sendcode); //向服务器发送数据
}
function showlist() //onreadystatechange 事件执行的方法
{
if(xmlhttprequest.readyState==4||xmlhttprequest.readyState=="complete")
{
//判断状态
document.getElementById("seachlist").innerHTML=""; //向容器DIV添加元素
var httptext = xmlhttprequest.responseText; //获取服务器返回字符串
var strtext = httptext.substring(0,httptext.indexOf('<'));//获取服务器发送过来的文本
var arry = new Array();
arry = strtext.split(',');
for(var i=0;i<arry.length;i++) //对其进行遍历
{
var div = document.createElement("DIV"); //创建子DIV
div.id = i; //设定ID
div.onblur= divonblur; //添加失去焦点事件
div.innerHTML="<SPAN onmouseover='mouseover();' onmouseout='mouseout();'>"+arry[i]+"</SPAN></br>";
//创建SPAN添加到子容器DIV中
document.getElementById("seachlist").appendChild(div);
//将子容器挂载到父容器中
}
divcss(); //判断是否隐藏
}
}
</script>
三。HTML表单部分
<body MS_POSITIONING="GridLayout">
<form id="Form1" method="post" runat="server">
<table width="100%">
<tr height="5%">
<td style="HEIGHT: 5%">
<asp:textbox id="seach" runat="server" autocomplete="off" CssClass="txt"></asp:textbox>
<input id="btn_seach" type="button" value="快速搜索"><br>
<div id="seachlist" onblur="divonblur()" ></div>
</td>
</tr>
</table>
</form>
</body>
<form id="Form1" method="post" runat="server">
<table width="100%">
<tr height="5%">
<td style="HEIGHT: 5%">
<asp:textbox id="seach" runat="server" autocomplete="off" CssClass="txt"></asp:textbox>
<input id="btn_seach" type="button" value="快速搜索"><br>
<div id="seachlist" onblur="divonblur()" ></div>
</td>
</tr>
</table>
</form>
</body>
四。服务器端代码
private SqlConnection con;
private DataTable tab;
private SqlDataAdapter sa;
private void Page_Load(object sender, System.EventArgs e)
{
this.seach.Attributes.Add("onkeyup","keyup()");
if(Request.QueryString["param"]!=null)
{
BinaryReader br = new BinaryReader(Request.InputStream);
byte [] b = new byte[Request.InputStream.Length];
br.Read(b,0,b.Length);
char []c = Encoding.UTF8.GetChars(b);
string str = new string(c);
string strparam = getmessage(str);
if(strparam!="")
Response.Write(strparam);
}
// 在此处放置用户代码以初始化页面
}
private string getmessage(string message)
{
string str ="";
if(con==null)
con = new SqlConnection("Server=(local);Database=pubs;uid=;pwd=");
sa = new SqlDataAdapter("select message from messages where message
like '"+message+"%'",con);
dt = new DataSet();
sa.Fill(dt,"message");
tab = dt.Tables[0];
for(int i=0;i<tab.Rows.Count;i++)
{
if(i==tab.Rows.Count-1)
str+=tab.Rows[i][0].ToString();
else
str+=tab.Rows[i][0].ToString()+",";
}
return str;
}
private DataTable tab;
private SqlDataAdapter sa;
private void Page_Load(object sender, System.EventArgs e)
{
this.seach.Attributes.Add("onkeyup","keyup()");
if(Request.QueryString["param"]!=null)
{
BinaryReader br = new BinaryReader(Request.InputStream);
byte [] b = new byte[Request.InputStream.Length];
br.Read(b,0,b.Length);
char []c = Encoding.UTF8.GetChars(b);
string str = new string(c);
string strparam = getmessage(str);
if(strparam!="")
Response.Write(strparam);
}
// 在此处放置用户代码以初始化页面
}
private string getmessage(string message)
{
string str ="";
if(con==null)
con = new SqlConnection("Server=(local);Database=pubs;uid=;pwd=");
sa = new SqlDataAdapter("select message from messages where message
like '"+message+"%'",con);
dt = new DataSet();
sa.Fill(dt,"message");
tab = dt.Tables[0];
for(int i=0;i<tab.Rows.Count;i++)
{
if(i==tab.Rows.Count-1)
str+=tab.Rows[i][0].ToString();
else
str+=tab.Rows[i][0].ToString()+",";
}
return str;
}