ASP.NET搭配Ajax實(shí)現(xiàn)搜索提示功能
平時(shí)的軟件開(kāi)發(fā)中,信息的搜索是經(jīng)常碰到的,增加搜索關(guān)鍵字提示是提高用戶體驗(yàn)的一種很好的辦法。今天就介紹下在ASP.NET如何利用AJAX來(lái)實(shí)現(xiàn)搜索的信息提示!
1.需要了解的一些知識(shí)點(diǎn)
(1)AJAX對(duì)象不同瀏覽器的創(chuàng)建
不同的瀏覽器對(duì)AJAX(XMLHttpRequest)對(duì)象的實(shí)現(xiàn)是不一樣的,例如IE瀏覽器是通過(guò)ActiveX控件來(lái)實(shí)現(xiàn)AJAX對(duì)象。而其他一些瀏覽器比如火狐,它將AJAX對(duì)象實(shí)現(xiàn)成了一個(gè)瀏覽器內(nèi)部的對(duì)象叫XMLHttpRequest,所以不同的瀏覽器創(chuàng)建AJAX對(duì)象的方式也就不同,那么我們來(lái)看看不同瀏覽器之間創(chuàng)建AJAX對(duì)象的方式:
在IE瀏覽器下面的創(chuàng)建:
//IE瀏覽器
try {
//IE5.0
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
//IE5.5 以上版本
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) { }
在火狐瀏覽器下面的創(chuàng)建:
//火狐, Safari 等瀏覽器 httpRequest = new XMLHttpRequest();
多瀏覽器AJAX對(duì)象創(chuàng)建函數(shù):
function createAjaxObj() {
var httpRequest = false;
//判斷是否包含XMLHttpRequest對(duì)象 PS:將來(lái)IE高也有可能繼承次對(duì)象
if (window.XMLHttpRequest) {
//火狐 , Safari 等瀏覽器
httpRequest = new XMLHttpRequest();
if (httpRequest.overrideMimeType)
httpRequest.overrideMimeType('text/xml');
}//判斷是否支持Active控件對(duì)象
else if (window.ActiveXObject) {
//IE瀏覽器
try {
//IE5.0
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
//IE5.5以上
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) { }
}
}
//返回創(chuàng)建好的AJAX對(duì)象
return httpRequest;
}
(2)文本框內(nèi)容改變的事件在不同瀏覽器下的使用
文本框內(nèi)容改變的事件目前來(lái)說(shuō)還沒(méi)有一個(gè)標(biāo)準(zhǔn)的版本。我們目前只關(guān)心IE與火狐好了,那么在IE和火狐下這兩個(gè)時(shí)間分別怎么表示呢?
IE: onpropertychange
FireFox: oninput
那么如何在頁(yè)面加載時(shí),根據(jù)瀏覽器給文本框附加對(duì)應(yīng)的change事件呢?
1.JS如何判斷瀏覽器版本
//IE瀏覽器
if (navigator.userAgent.indexOf("MSIE") > 0)
{ }
//火狐瀏覽器
if (isFirefox = navigator.userAgent.indexOf("Firefox") > 0)
{}
2.根據(jù)瀏覽器版本給文本框附加對(duì)應(yīng)事件
function getOs() {
//判斷瀏覽器類型
if (navigator.userAgent.indexOf("MSIE") > 0) {
//此時(shí)假設(shè)文本框id為'txtSearch'
//為文本框附加IE所支持的事件
document.getElementById('txtSearch').attachEvent("onpropertychange", search);
OsTyep = "MSIE";
} else if (navigator.userAgent.indexOf("Firefox") > 0) {
//此時(shí)假設(shè)文本框id為'txtSearch'
//為文本框附加火狐所支持的事件
document.getElementById('txtSearch').addEventListener("input", search, false);
OsTyep = "Firefox";
}
}
3.根據(jù)瀏覽器版本給文本框清除對(duì)應(yīng)事件
function ClearOS() {
if (navigator.userAgent.indexOf("MSIE") > 0) {
//此時(shí)假設(shè)文本框id為'txtSearch'
//為文本框清除IE所支持的事件
document.getElementById('txtSearch').detachEvent("onpropertychange", search);
OsTyep = "MSIE";
} else if (navigator.userAgent.indexOf("Firefox") > 0) {
//此時(shí)假設(shè)文本框id為'txtSearch'
//為文本框清除火狐所支持的事件
document.getElementById('txtSearch').removeEventListener("input", search, false);
OsTyep = "Firefox";
}
}
二、客戶端的設(shè)計(jì)
(1)實(shí)現(xiàn)流程的分析
了解完以上知識(shí)點(diǎn)之后,我們來(lái)看一下實(shí)現(xiàn)搜索提示的一個(gè)整體流程:
1) 首先客戶端通過(guò)文本框輸入事件捕獲輸入的關(guān)鍵字
2) 在通過(guò)我們之前創(chuàng)建好的AJAX對(duì)象提交給服務(wù)器
3) 服務(wù)器接受提交的關(guān)鍵字,進(jìn)行查詢將結(jié)果集返回給客戶端進(jìn)行顯示
流程如下:

(2)樣式的編寫
那么接下來(lái)我們來(lái)看一下樣式,其中包括當(dāng)文本框鼠標(biāo)移動(dòng)上去給邊框加顏色與搜索結(jié)果行選中的樣式等,這里就不細(xì)說(shuō)了,列舉出來(lái)供參考:
<style type="text/css" media="screen">
body
{
font:11px arial;
}
/*設(shè)置提示提示列表上的樣式表*/
.search_link
{
background-color:#FFFFFF;
cursor: pointer;
line-height:24px;
text-indent:6px;
}
/*設(shè)置當(dāng)鼠標(biāo)移動(dòng)到提示列表上的樣式表*/
.search_link_over
{
background-color:#E8F2FE;
cursor: pointer;
line-height:24px;
text-indent:6px;
}
/*設(shè)置顯示搜索提示div的樣式表*/
#search_div
{
position:absolute;
background-color:#FFFFFF;
text-align:left;
border:1px solid #000000;
border-top:0px;
display:none;
min-width:553px;
width:553px;
}
/*文本框樣式*/
.mainInput {
line-height: 26px;
height: 28px;
width: 550px;
font-size: 16px;
font-family: "微軟雅黑", "宋體", Candara;
font-weight: normal;
color: #666;
margin: auto;
border: none;
text-indent: 8px;
}
/*鼠標(biāo)放上文本框樣式*/
.mainInputOver {
width:552px;
height:30px;
border-top-width: 1px;
border-right-width: 1px;
border-bottom-width: 1px;
border-left-width: 1px;
border-top-style: solid;
border-right-style: solid;
border-bottom-style: solid;
border-left-style: solid;
border-top-color: #b7b7b7;
border-right-color: #d0d0d0;
border-bottom-color: #d0d0d0;
border-left-color: #d0d0d0;
}
/*鼠標(biāo)離開(kāi)文本框樣式*/
.mainInputFocus {
width:552px;
height:30px;
border: 1px solid #41b5f2;
}
/*點(diǎn)擊文本框樣式*/
.myBorder
{
width:552px;
height:30px;
border-top: 1px solid #CCCCCC;
border-bottom: 1px solid #DDDDDD;
border-left: 1px solid #DDDDDD;
border-right: 1px solid #DDDDDD;
}
</style>
(3)aspx頁(yè)面與ajax_search.js文件的編寫
接下來(lái)就是一個(gè)比較重要的環(huán)節(jié)了,aspx頁(yè)面與ajax_search.js文件中包含了整體包括顯示與請(qǐng)求的方法例如:
1.頁(yè)面的實(shí)現(xiàn)
<body onload="getOs()" onkeydown="if(event.keyCode==13)return false;"> <form id="form1" runat="server"> <div> <div class="myBorder" onmouseover="this.className='mainInputOver'" onmouseout="this.className='myBorder'" onclick="this.className='mainInputFocus'"> <input type="text" id="txtSearch" name="txtSearch" onblur="HiddenDiv()" alt="SearchCriteria" autocomplete="off" class="mainInput" /> </div> <!--該DIV作為現(xiàn)實(shí)搜索提示的結(jié)果--> <div id="search_div" style="margin-top:0px" ></div> </div> </form> </body>
2.根據(jù)瀏覽器創(chuàng)建AJAX對(duì)象
var searchReq = createAjaxObj();
var OsTyep = '';
function getOs() {
//判斷瀏覽器類型
if (navigator.userAgent.indexOf("MSIE") > 0) {
document.getElementById('txtSearch').attachEvent("onpropertychange", search);
OsTyep = "MSIE";
} else if (navigator.userAgent.indexOf("Firefox") > 0) {
document.getElementById('txtSearch').addEventListener("input", search, false);
OsTyep = "Firefox";
}
}
function ClearOS() {
if (navigator.userAgent.indexOf("MSIE") > 0) {
document.getElementById('txtSearch').detachEvent("onpropertychange", search);
OsTyep = "MSIE";
} else if (navigator.userAgent.indexOf("Firefox") > 0) {
document.getElementById('txtSearch').removeEventListener("input", search, false);
OsTyep = "Firefox";
}
}
function createAjaxObj() {
var httpRequest = false;
//判斷是否包含XMLHttpRequest對(duì)象 PS:將來(lái)IE高也有可能繼承次對(duì)象
if (window.XMLHttpRequest) {
//火狐 , Safari 等瀏覽器
httpRequest = new XMLHttpRequest();
if (httpRequest.overrideMimeType)
httpRequest.overrideMimeType('text/xml');
//ie: onpropertychange
//ff: oninput
} //判斷是否支持Active控件對(duì)象
else if (window.ActiveXObject) {
//IE瀏覽器
try {
//IE5.0
httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
//IE5.5以上
httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) { }
}
}
//返回創(chuàng)建好的AJAX對(duì)象
return httpRequest;
}
3.創(chuàng)建請(qǐng)求與返回?cái)?shù)據(jù)的顯示
//異步請(qǐng)求服務(wù)器獲取搜索結(jié)果
function search() {
if (searchReq.readyState == 4 || searchReq.readyState == 0) {
//獲得文本框中的值
var valStr = escape(document.getElementById("txtSearch").value);
//建立連接
searchReq.open("GET", encodeURI('Search.ashx?search=' + valStr+'&fresh=' + Math.random()), true);
//當(dāng)請(qǐng)求狀態(tài)改變時(shí)調(diào)用 handleSearch方法
searchReq.onreadystatechange = handleSearch;
searchReq.send(null);
}
}
//返回結(jié)果處理方法
function handleSearch() {
if (searchReq.readyState == 4) {
//獲得搜索提示結(jié)果的元素DIV
var searchDIV = document.getElementById("search_div");
searchDIV.innerHTML = "";
//用^將返回的文本數(shù)據(jù)分割成數(shù)組
var resultStrArr = searchReq.responseText.split("^");
//循環(huán)構(gòu)建HTML代碼
for (var i = 0; i < resultStrArr.length - 1; i++) {
var htmlStr = '<div onmouseover="selectOverDiv(this,'+i+');" ';
htmlStr += 'onmouseout="selectOutDiv(this,'+i+');" ';
htmlStr += 'onclick="setSearch(this.innerHTML);" ';
htmlStr += 'class="search_link " style="display:block;width:100%;" >' + resultStrArr[i] + '</div>';
searchDIV.innerHTML += htmlStr;
}
ShowDiv();
x = -1;
}
}
4.將數(shù)據(jù)選中數(shù)據(jù)顯示文本框中
上邊代碼中在循環(huán)構(gòu)建HTML代碼時(shí),我們給構(gòu)建的DIV加入了三個(gè)事件分別是:
1 onmouseover="selectOverDiv(this,'+i+');"
當(dāng)鼠標(biāo)放上去時(shí)調(diào)用selectOverDiv函數(shù)傳遞自己進(jìn)去
2 onmouseout="selectOutDiv(this,'+i+');"
當(dāng)鼠標(biāo)放上去時(shí)調(diào)用selectOutDiv函數(shù)傳遞自己進(jìn)去
3 onclick="setSearch(this.innerHTML);"
當(dāng)鼠標(biāo)點(diǎn)擊DIV時(shí)調(diào)用setSearch函數(shù)傳入本身DIV中內(nèi)容
那么還是來(lái)看下這幾個(gè)方法的實(shí)現(xiàn)吧:
function selectOverDiv(div_value, i) {
div_value.className = "search_link_over";
var my_div = document.getElementById("search_div").getElementsByTagName("div")
var the_num = my_div.length;
for (var k = 0; k < the_num; k++) {
selectOut(my_div[k]);
if (k == i) {
selectOver(my_div[k])
}
}
isCheckDiv = true;
x = i;
}
function selectOutDiv(div_value,i) {
isCheckDiv = false;
div_value.className = "search_link";
x = i;
}
function setSearch(value) {
//清空文本框的內(nèi)容改變事件是因?yàn)槲覀兘o選中值復(fù)制時(shí) 該事件會(huì)觸發(fā)
//所以先清空次事件
ClearOS();
document.getElementById("txtSearch").value = value;
//設(shè)置該屬性為false 在調(diào)用HiddenDiv函數(shù)會(huì)隱藏提示結(jié)果DIV
isCheckDiv = false;
HiddenDiv();
//在賦值完成后再次附加修改時(shí)間
getOs();
}
function ShowDiv() {
var content = document.getElementById("txtSearch").value;
var divConten = document.getElementById("search_div").innerHTML;
if (content != '' && divConten != '') {
document.getElementById("search_div").style.display = "block"
} else {
isCheckDiv = false;
HiddenDiv();
}
}
function HiddenDiv() {
if (isCheckDiv == false) {
document.getElementById("search_div").style.display = "none";
document.getElementById("search_div").innerHTML = '';
}
}
5.增加鍵盤上下鍵選中提示數(shù)據(jù)與回車鍵選中數(shù)據(jù)到文本框
var index = -1; //表示當(dāng)前選中的行索引
function keyDown() {
var value = event.keyCode
//向上38,向下40,回車13
var the_key = event.keyCode
//判斷提示DIV是否是現(xiàn)實(shí)狀態(tài)
if (document.getElementById("search_div").style.display != "none") {
//獲取里面所用行
var my_div = document.getElementById("search_div").getElementsByTagName("div")
var the_num = my_div.length;
switch (the_key) {
case 40: //向下
//判斷index是否已經(jīng)到最下面
if (index == the_num - 1) {
index = 0;
} else {
index++;
}
//清楚所有選中
for (var i = 0; i < the_num; i++) {
selectOut(my_div[i]);
}
//根據(jù)index選中對(duì)應(yīng)索引行
for (i = 0; i < the_num; i++) {
if (i == index) {
selectOver(my_div[i])
}
}
break;
case 38: //向上
//判斷index是否已經(jīng)到最上面
if (index == 0) {
index = the_num-1;
} else { index--; }
//清楚所有選中
for (var i = 0; i < the_num; i++) {
selectOut(my_div[i]);
}
//根據(jù)index選中對(duì)應(yīng)索引行
for (i = 0; i < the_num; i++) {
if (i == index) {
selectOver(my_div[i])
}
}
break;
case 13: //回車
//將選中的內(nèi)容放入文本框中
if (my_div[index].innerHTML != null) {
setSearch(my_div[index].innerHTML);
}
break;
}
}
}
document.onkeydown = keyDown;
3.服務(wù)器端的設(shè)計(jì)
(1)實(shí)現(xiàn)一個(gè)虛擬的數(shù)據(jù)源
前臺(tái)傳來(lái)關(guān)鍵字,后臺(tái)必須要有數(shù)據(jù)匹配,為了簡(jiǎn)單我就不建立數(shù)據(jù)庫(kù)了 我就模擬一個(gè)數(shù)據(jù)源好啦!
步驟:右鍵項(xiàng)目 --> 添加新項(xiàng)--> 選擇一般處理程序命名為:Search.ashx 編寫代碼如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data;
using System.Data.SqlClient;
using System.Text;
using System.CodeDom;
using System.Globalization;
using System.ComponentModel;
using System.Collections;
public class Search : IHttpHandler {
//定義一個(gè)數(shù)據(jù)源
public List<string> DataSource
{
get
{
List<string> list = new List<string>()
{
"我愛(ài)C#",
"我愛(ài).NET",
"我愛(ài)微軟技術(shù)"
};
return list;
}
}
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
}
public bool IsReusable {
get {
return false;
}
}
}
(2)搜索數(shù)據(jù)源返回固定格式數(shù)據(jù)以字符串形式
緊接著我們要在ProcessReques方法中加入我們搜索數(shù)據(jù)源構(gòu)建返回相應(yīng)數(shù)據(jù)集,拼接結(jié)果字符串返回給客戶端。代碼如下:
public void ProcessRequest (HttpContext context) {
context.Response.ContentType = "text/plain";
//接受客戶端關(guān)鍵字并且解碼
string searchStr = HttpUtility.UrlDecode(context.Request.QueryString["search"].ToString(), System.Text.Encoding.UTF8);
//搜索數(shù)據(jù)源集合中匹配的關(guān)鍵字
var result = (from string n in DataSource
where n.Contains(searchStr)
select n).ToList<string>();
StringBuilder sb = new StringBuilder(100);
//將匹配關(guān)鍵字用符號(hào)^ 分割拼接成字符串
foreach (string str in result as List<string>)
{
sb.AppendFormat("{0}^", str);
}
//返回客戶端
context.Response.Write(sb.ToString());
}
那么我們的基于AJAX的搜索提示功能就順利的完成了,運(yùn)行效果如下:

以上就是ASP.NET利用AJAX實(shí)現(xiàn)搜索提示的實(shí)現(xiàn)過(guò)程,內(nèi)容很詳細(xì),思路也很清晰,希望對(duì)大家的學(xué)習(xí)有所幫助。
- 使用Ajax模仿百度搜索框的自動(dòng)提示功能實(shí)例
- Servlet+Ajax實(shí)現(xiàn)智能搜索框智能提示功能
- Ajax實(shí)現(xiàn)智能提示搜索功能
- 利用AjaxControlToolkit實(shí)現(xiàn)百度搜索時(shí)的下拉列表提示詳細(xì)步驟
- php+ajax做仿百度搜索下拉自動(dòng)提示框(有實(shí)例)
- asp+ajax仿google搜索提示效果代碼
- asp.net+js實(shí)現(xiàn)的ajax sugguest搜索提示效果
- ajax Suggest類似google的搜索提示效果
- Ajax實(shí)現(xiàn)搜索框提示功能
相關(guān)文章
ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection)中篇
這篇文章主要為大家再一次介紹了ASP.NET Core 數(shù)據(jù)保護(hù)(Data Protection),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09
VB.NET調(diào)用MySQL存儲(chǔ)過(guò)程并獲得返回值的方法
這篇文章主要介紹了VB.NET調(diào)用MySQL存儲(chǔ)過(guò)程并獲得返回值的方法,涉及基于VB.NET操作MySQL數(shù)據(jù)庫(kù)的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-07-07
ASP.NET列出數(shù)據(jù)庫(kù)活躍鏈接的方法
這篇文章主要介紹了ASP.NET列出數(shù)據(jù)庫(kù)活躍鏈接的方法,實(shí)例分析了asp.net列出數(shù)據(jù)庫(kù)活躍鏈接的原理與實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-06-06
vs2010出現(xiàn)error MSB8008的解決方法
這篇文章主要為大家詳細(xì)介紹了vs2010問(wèn)題error MSB8008: 指定的平臺(tái)工具集(v110)未安裝或無(wú)效的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06
asp.net發(fā)送郵件實(shí)現(xiàn)方法
這篇文章主要介紹了asp.net發(fā)送郵件實(shí)現(xiàn)方法,以一個(gè)具體實(shí)例的形式詳細(xì)講述了asp.net發(fā)送郵件的技巧,需要的朋友可以參考下2014-10-10

