平時(shí)的軟件開發(fā)中,信息的搜索是經(jīng)常碰到的,增加搜索關(guān)鍵字提示是提高用戶體驗(yàn)的一種很好的辦法。今天就介紹下在ASP.NET如何利用AJAX來實(shí)現(xiàn)搜索的信息提示!
1.需要了解的一些知識點(diǎn)
(1)AJAX對象不同瀏覽器的創(chuàng)建
不同的瀏覽器對AJAX(XMLHttpRequest)對象的實(shí)現(xiàn)是不一樣的,例如IE瀏覽器是通過ActiveX控件來實(shí)現(xiàn)AJAX對象。而其他一些瀏覽器比如火狐,它將AJAX對象實(shí)現(xiàn)成了一個(gè)瀏覽器內(nèi)部的對象叫XMLHttpRequest,所以不同的瀏覽器創(chuàng)建AJAX對象的方式也就不同,那么我們來看看不同瀏覽器之間創(chuàng)建AJAX對象的方式:
在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對象創(chuàng)建函數(shù):
function createAjaxObj() {
var httpRequest = false;
//判斷是否包含XMLHttpRequest對象 PS:將來IE高也有可能繼承次對象
if (window.XMLHttpRequest) {
//火狐 , Safari 等瀏覽器
httpRequest = new XMLHttpRequest();
if (httpRequest.overrideMimeType)
httpRequest.overrideMimeType('text/xml');
}//判斷是否支持Active控件對象
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對象
return httpRequest;
}
(2)文本框內(nèi)容改變的事件在不同瀏覽器下的使用
文本框內(nèi)容改變的事件目前來說還沒有一個(gè)標(biāo)準(zhǔn)的版本。我們目前只關(guān)心IE與火狐好了,那么在IE和火狐下這兩個(gè)時(shí)間分別怎么表示呢?
IE: onpropertychange
FireFox: oninput
那么如何在頁面加載時(shí),根據(jù)瀏覽器給文本框附加對應(yīng)的change事件呢?
1.JS如何判斷瀏覽器版本
//IE瀏覽器
if (navigator.userAgent.indexOf("MSIE") > 0)
{ }
//火狐瀏覽器
if (isFirefox = navigator.userAgent.indexOf("Firefox") > 0)
{}
2.根據(jù)瀏覽器版本給文本框附加對應(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ù)瀏覽器版本給文本框清除對應(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)流程的分析
了解完以上知識點(diǎn)之后,我們來看一下實(shí)現(xiàn)搜索提示的一個(gè)整體流程:
1) 首先客戶端通過文本框輸入事件捕獲輸入的關(guān)鍵字
2) 在通過我們之前創(chuàng)建好的AJAX對象提交給服務(wù)器
3) 服務(wù)器接受提交的關(guān)鍵字,進(jìn)行查詢將結(jié)果集返回給客戶端進(jìn)行顯示
流程如下:
![](http://img.jbzj.com/file_images/article/201509/2015928142409250.png?2015828142458)
(2)樣式的編寫
那么接下來我們來看一下樣式,其中包括當(dāng)文本框鼠標(biāo)移動上去給邊框加顏色與搜索結(jié)果行選中的樣式等,這里就不細(xì)說了,列舉出來供參考:
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)移動到提示列表上的樣式表*/
.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)離開文本框樣式*/
.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頁面與ajax_search.js文件的編寫
接下來就是一個(gè)比較重要的環(huán)節(jié)了,aspx頁面與ajax_search.js文件中包含了整體包括顯示與請求的方法例如:
1.頁面的實(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對象
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對象 PS:將來IE高也有可能繼承次對象
if (window.XMLHttpRequest) {
//火狐 , Safari 等瀏覽器
httpRequest = new XMLHttpRequest();
if (httpRequest.overrideMimeType)
httpRequest.overrideMimeType('text/xml');
//ie: onpropertychange
//ff: oninput
} //判斷是否支持Active控件對象
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對象
return httpRequest;
}
3.創(chuàng)建請求與返回?cái)?shù)據(jù)的顯示
//異步請求服務(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)請求狀態(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)容
那么還是來看下這幾個(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í) 該事件會觸發(fā)
//所以先清空次事件
ClearOS();
document.getElementById("txtSearch").value = value;
//設(shè)置該屬性為false 在調(diào)用HiddenDiv函數(shù)會隱藏提示結(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選中對應(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選中對應(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ù)源
前臺傳來關(guān)鍵字,后臺必須要有數(shù)據(jù)匹配,為了簡單我就不建立數(shù)據(jù)庫了 我就模擬一個(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 Liststring> DataSource
{
get
{
Liststring> list = new Liststring>()
{
"我愛C#",
"我愛.NET",
"我愛微軟技術(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).ToListstring>();
StringBuilder sb = new StringBuilder(100);
//將匹配關(guān)鍵字用符號^ 分割拼接成字符串
foreach (string str in result as Liststring>)
{
sb.AppendFormat("{0}^", str);
}
//返回客戶端
context.Response.Write(sb.ToString());
}
那么我們的基于AJAX的搜索提示功能就順利的完成了,運(yùn)行效果如下:
![](http://img.jbzj.com/file_images/article/201509/2015928142512117.png?2015828142520)
以上就是ASP.NET利用AJAX實(shí)現(xiàn)搜索提示的實(shí)現(xiàn)過程,內(nèi)容很詳細(xì),思路也很清晰,希望對大家的學(xué)習(xí)有所幫助。
您可能感興趣的文章:- jquery ajax請求方式與提示用戶正在處理請稍等
- php+ajax做仿百度搜索下拉自動提示框(有實(shí)例)
- ajax 自動完成下拉框 自動提示位置問題
- asp+ajax仿google搜索提示效果代碼
- 使用jQuery全局事件ajaxStart為特定請求實(shí)現(xiàn)提示效果的代碼
- ajax Suggest類似google的搜索提示效果
- jquery formValidator插件ajax驗(yàn)證 內(nèi)容不做任何修改再離開提示錯(cuò)誤的bug解決方法
- asp.net+js實(shí)現(xiàn)的ajax sugguest搜索提示效果
- ajax實(shí)時(shí)任務(wù)提示功能的實(shí)現(xiàn)代碼
- Ajax實(shí)現(xiàn)智能提示搜索功能