平時的軟體開發中,資訊的搜尋是經常碰到的,增加搜尋索引鍵提示是提高使用者體驗的一種很好的辦法。今天就介紹下在ASP.NET如何利用AJAX來實現搜尋的資訊提示!
1.需要瞭解的一些知識點
(1)AJAX對象不同瀏覽器的建立
不同的瀏覽器對AJAX(XMLHttpRequest)對象的實現是不一樣的,例如IE瀏覽器是通過ActiveX控制項來實現AJAX對象。而其他一些瀏覽器比如Firefox,它將AJAX對象實現成了一個瀏覽器內部的對象叫XMLHttpRequest,所以不同的瀏覽器建立AJAX對象的方式也就不同,那麼我們來看看不同瀏覽器之間建立AJAX對象的方式:
在IE瀏覽器下面的建立:
//IE瀏覽器 try { //IE5.0 httpRequest = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { //IE5.5 以上版本 httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { }
在Firefox瀏覽器下面的建立:
//Firefox, Safari 等瀏覽器httpRequest = new XMLHttpRequest();
多瀏覽器AJAX對象建立函數:
function createAjaxObj() { var httpRequest = false; //判斷是否包含XMLHttpRequest對象 PS:將來IE高也有可能繼承次對象 if (window.XMLHttpRequest) { //Firefox , 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) { } } } //返回建立好的AJAX對象 return httpRequest;}
(2)文字框內容改變的事件在不同瀏覽器下的使用
文字框內容改變的事件目前來說還沒有一個標準的版本。我們目前只關心IE與Firefox好了,那麼在IE和Firefox下這兩個時間分別怎麼表示呢?
IE: onpropertychange
FireFox: oninput
那麼如何在頁面載入時,根據瀏覽器給文字框附加對應的change事件呢?
1.JS如何判斷瀏覽器版本
//IE瀏覽器if (navigator.userAgent.indexOf("MSIE") > 0){ }//Firefox瀏覽器if (isFirefox = navigator.userAgent.indexOf("Firefox") > 0){}
2.根據瀏覽器版本給文字框附加對應事件
function getOs() { //判斷瀏覽器類型 if (navigator.userAgent.indexOf("MSIE") > 0) { //此時假設文字框id為'txtSearch' //為文字框附加IE所支援的事件 document.getElementById('txtSearch').attachEvent("onpropertychange", search); OsTyep = "MSIE"; } else if (navigator.userAgent.indexOf("Firefox") > 0) { //此時假設文字框id為'txtSearch' //為文字框附加Firefox所支援的事件 document.getElementById('txtSearch').addEventListener("input", search, false); OsTyep = "Firefox"; }}
3.根據瀏覽器版本給文字框清除對應事件
function ClearOS() {
if (navigator.userAgent.indexOf("MSIE") > 0) {
//此時假設文字框id為'txtSearch'
//為文字框清除IE所支援的事件
document.getElementById('txtSearch').detachEvent("onpropertychange", search);
OsTyep = "MSIE";
} else if (navigator.userAgent.indexOf("Firefox") > 0) {
//此時假設文字框id為'txtSearch'
//為文字框清除Firefox所支援的事件
document.getElementById('txtSearch').removeEventListener("input", search, false);
OsTyep = "Firefox";
}
}
二、用戶端的設計
(1)實現流程的分析
瞭解完以上知識點之後,我們來看一下實現搜尋提示的一個整體流程:
1) 首先用戶端通過文字框輸入事件捕獲輸入的關鍵字
2) 在通過我們之前建立好的AJAX對象提交給伺服器
3) 伺服器接受提交的關鍵字,進行查詢將結果集返回給用戶端進行顯示
流程如下:
(2)樣式的編寫
那麼接下來我們來看一下樣式,其中包括當文字框滑鼠移動上去給邊框加顏色與搜尋結果行選中的樣式等,這裡就不細說了,列舉出來供參考:
<style type="text/css" media="screen"> body { font:11px arial; } /*設定提示提示列表上的樣式表*/ .search_link { background-color:#FFFFFF; cursor: pointer; line-height:24px; text-indent:6px; } /*設定當滑鼠移動到提示列表上的樣式表*/ .search_link_over { background-color:#E8F2FE; cursor: pointer; line-height:24px; text-indent:6px; } /*設定顯示搜尋提示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;} /*滑鼠放上文字框樣式*/ .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;}/*滑鼠離開文字框樣式*/.mainInputFocus { width:552px; height:30px; border: 1px solid #41b5f2;}/*點擊文字框樣式*/.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檔案的編寫
接下來就是一個比較重要的環節了,aspx頁面與ajax_search.js檔案中包含了整體包括顯示與請求的方法例如:
1.頁面的實現
<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作為現實搜尋提示的結果--> <div id="search_div" style="margin-top:0px" ></div> </div> </form></body>
2.根據瀏覽器建立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) { //Firefox , 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) { } } } //返回建立好的AJAX對象 return httpRequest;}
3.建立請求與返回資料的顯示
//非同步請求伺服器擷取搜尋結果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); //當請求狀態改變時調用 handleSearch方法 searchReq.onreadystatechange = handleSearch; searchReq.send(null); }}//返回結果處理方法function handleSearch() { if (searchReq.readyState == 4) { //獲得搜尋提示結果的元素DIV var searchDIV = document.getElementById("search_div"); searchDIV.innerHTML = ""; //用^將返回的文本資料分割成數組 var resultStrArr = searchReq.responseText.split("^"); //迴圈構建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.將資料選中資料顯示文字框中
上邊代碼中在迴圈構建HTML代碼時,我們給構建的DIV加入了三個事件分別是:
1 onmouseover="selectOverDiv(this,'+i+');"
當滑鼠放上去時調用selectOverDiv函數傳遞自己進去
2 onmouseout="selectOutDiv(this,'+i+');"
當滑鼠放上去時調用selectOutDiv函數傳遞自己進去
3 onclick="setSearch(this.innerHTML);"
當滑鼠點擊DIV時調用setSearch函數傳入本身DIV中內容
那麼還是來看下這幾個方法的實現吧:
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) { //清空文字框的內容改變事件是因為我們給選中值複製時 該事件會觸發 //所以先清空次事件 ClearOS(); document.getElementById("txtSearch").value = value; //設定該屬性為false 在調用HiddenDiv函數會隱藏提示結果DIV isCheckDiv = false; HiddenDiv(); //在賦值完成後再次附加修改時間 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.增加鍵盤上下鍵選中提示資料與斷行符號鍵選中資料到文字框
var index = -1; //表示當前選中的行索引function keyDown() { var value = event.keyCode //向上38,向下40,斷行符號13 var the_key = event.keyCode //判斷提示DIV是否是現實狀態 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是否已經到最下面 if (index == the_num - 1) { index = 0; } else { index++; } //清楚所有選中 for (var i = 0; i < the_num; i++) { selectOut(my_div[i]); } //根據index選中對應索引行 for (i = 0; i < the_num; i++) { if (i == index) { selectOver(my_div[i]) } } break; case 38: //向上 //判斷index是否已經到最上面 if (index == 0) { index = the_num-1; } else { index--; } //清楚所有選中 for (var i = 0; i < the_num; i++) { selectOut(my_div[i]); } //根據index選中對應索引行 for (i = 0; i < the_num; i++) { if (i == index) { selectOver(my_div[i]) } } break; case 13: //斷行符號 //將選中的內容放入文字框中 if (my_div[index].innerHTML != null) { setSearch(my_div[index].innerHTML); } break; } }}document.onkeydown = keyDown;
3.伺服器端的設計
(1)實現一個虛擬資料來源
前台傳來關鍵字,後台必須要有資料匹配,為了簡單我就不建立資料庫了 我就類比一個資料來源好啦!
步驟:右鍵項目 --> 添加新項--> 選擇一般處理常式命名為: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 { //定義一個資料來源 public List<string> DataSource { get { List<string> list = new List<string>() { "我愛C#", "我愛.NET", "我愛微軟技術" }; return list; } } public void ProcessRequest (HttpContext context) { context.Response.ContentType = "text/plain"; } public bool IsReusable { get { return false; } }}
(2)搜尋資料來源返回固定格式資料以字串形式
緊接著我們要在ProcessReques方法中加入我們搜尋資料來源構建返回相應資料集,拼接結果字串返回給用戶端。代碼如下:
public void ProcessRequest (HttpContext context) { context.Response.ContentType = "text/plain"; //接受用戶端關鍵字並且解碼 string searchStr = HttpUtility.UrlDecode(context.Request.QueryString["search"].ToString(), System.Text.Encoding.UTF8); //搜尋資料來源集合中匹配的關鍵字 var result = (from string n in DataSource where n.Contains(searchStr) select n).ToList<string>(); StringBuilder sb = new StringBuilder(100); //將匹配關鍵字用符號^ 分割拼接成字串 foreach (string str in result as List<string>) { sb.AppendFormat("{0}^", str); } //返回用戶端 context.Response.Write(sb.ToString()); }
那麼我們的基於AJAX的搜尋提示功能就順利的完成了,運行效果如下:
以上就是ASP.NET利用AJAX實現搜尋提示的實現過程,內容很詳細,思路也很清晰,希望對大家的學習有所協助。