(3)aspx页面与ajax_search.js文件的编写

                   接下来就是一个比较重要的环节了,aspx页面与ajax_search.js文件中包含了整体包括显示与请求的方法例如:

                    1.页面的实现                    2.根据浏览器创建AJAX对象                    3.创建请求与返回数据的显示                    4.将数据选中数据显示文本框中

< 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 >

 

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) { }
        }
    }
    
// 返回创建好的AJAX对象
     return  httpRequest;
}

 

// 异步请求服务器获取搜索结果
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 οnmοuseοver="selectOverDiv(this, ' + i + ' );"  ' ;
            htmlStr 
+=   ' οnmοuseοut="selectOutDiv(this, ' + i + ' );"  ' ;
            htmlStr 
+=   ' οnclick="setSearch(this.innerHTML);"  ' ;
            htmlStr 
+=   ' class="search_link " style="display:block;width:100%;" > '   +  resultStrArr[i]  +   ' </div> ' ;

            searchDIV.innerHTML 
+=  htmlStr;
        }
        ShowDiv();
        x 
=   - 1 ;
    }
}

 

                       上边代码中在循环构建HTML代码时,我们给构建的DIV加入了三个事件分别是:

                        1 οnmοuseοver="selectOverDiv(this,'+i+');" 

                           当鼠标放上去时调用selectOverDiv函数传递自己进去

                        2 οnmοuseοut="selectOutDiv(this,'+i+');" 

                           当鼠标放上去时调用selectOutDiv函数传递自己进去

                        3 οnclick="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  Proce***equest (HttpContext context) {
        context.Response.ContentType 
=   " text/plain " ;
    }
 
    
public   bool  IsReusable {
        
get  {
            
return   false ;
        }
    }

}

 

           (2)搜索数据源返回固定格式数据以字符串形式

             紧接着我们要在Proce***eques方法中加入我们搜索数据源构建返回相应数据集,拼接结果字符串返回给客户端。代码如下:

   public   void  Proce***equest (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的搜索提示功能就顺利的完成了,运行效果如下:

     需要代码的朋友可以留下您的邮箱,我会将代码发送到提供的邮箱中!