Web前端设计模式--构建Ajax智能搜索...

设计场景:

        Ben最近负责的购书网出现了一点小问题,有很多客户抱怨说他们的搜索不够智能,因为网站有一个比较大的版块是关于老年人生活的书籍列表,这些老年人并不能够很清楚的记住他们所要查找书籍的完整名称...而网站的模糊搜索却无法提供有效的提示,这使得搜索存在很大的不足,于是公司要求Ben来解决这个问题。Ben的想法是做个有效地,及时的弹出层,当用户搜索的时候,随着用户键入的内容的变化,把数据库对应相似的信息不断的调出,返回给用户,这样就能的给用户提供及时有效的提示信息...

 

设计目标:

     提供有效的,及时的提示,方便用户查找信息... 

 

解决方案:

   给出的原始界面如下:

 

   第一步,我们先写一个储备样式,这个样式应用于弹出的数据提示层的..

  

代码
 
   
#searchDiv
{
position
: absolute ; //绝对定位
z-index
: 999 ; //元素的叠加次序,让它显示在其他元素之上
border
: solid 1px lightblue ;
background-color
: #ffffff ;
}

#searchDiv p
{
height
: 30px ;
width
: 362px ;
margin
: 0px ;
padding
: 0px ;
vertical-align
: text-bottom ;
font-size
: 13px ;
font-weight
: bolder ;
cursor
: pointer ;
}

 

下面是脚本,在键盘按键释放时,我们根据txtSearch中的内容来动态查询数据库的信息,将有关的信息全部调出,追加一个层,并把信息显示在层里面

 

代码
 
   
$( " #txtSearch " ).keyup( function (event){


if (event.keyCode != " 38 " && event.keyCode != " 40 " ) // 排除向上和向下键,以避免跟Document的keyup起冲突
{
pointRow
=- 1 ; // 这句话很重要,重置pointRow的值,因此当txtSearch中的搜索内容改变时,不会使用上次的pointRow脏数据

// 下面这段话用以设置搜索结果的信息框的位置,它紧贴在txtSearch这个查找框的下面,形成一个下拉的假象
$( " #searchDiv " ).remove();
var leftS = $( this ).offset().left;
var topS = $( this ).offset().top + $( this ).height() + 4 ;
var widthS = $( this ).width() + 2 ;


// 开始执行查找结果的载入
if ($( this ).val() != "" )
{
var waiting = " <img src='./images/loading.gif'/>&nbsp;&nbsp;数据载入中! " ; // 这边设置延迟载入的内容
searchDiv(leftS,topS,widthS,waiting); // 加载显示一个延迟框

$.ajax({
// 利用Ajax调用Web服务中的数据,实现与后台交互
type: " POST " ,
contentType:
" application/json;utf-8 " ,
url:
" ./WebService.asmx/GetDate " ,
data:
" {searchStr:' " + $( this ).val() + " '} " ,
dataType:
' json ' ,
anysc:
false ,
success:
function (data)
{
// XmlHttpRequest向服务器发送请求,并将获取最终的数据
if (data.d != "" )
{
setTimeout(
function (){ // 为了显示延迟效果,这边故意自己设置了0.3秒的延迟,0.3秒结束后,将后台的数据载入,替代了信息延迟提示框的内容...
$( " #searchDiv " ).remove(); // 去除信息延迟提示框
searchDiv(leftS,topS,widthS,data.d); // 加载最终从后台提取的内容
}, 300 );
}

else $( " #searchDiv " ).remove();
}
})
}

else $( " #searchDiv " ).remove();
}
})
 
 
//追加的信息弹出层
function searchDiv(leftS,topS,widthS,dataS)
{
     var popDiv="<div id='searchDiv'>"+dataS+"</div>";
     $('body').append(popDiv);
     $("#searchDiv").css({"left":leftS,"top":topS,"width":widthS,"height":"auto"});
}
 
 

 

执行顺序如下

(1)当从搜索框中键入需要查找的内容时,我们先调用的是延迟框,提示数据延迟显示,如下图:

 

 

(2)如果Ajax调到的后台数据不为空的话,则显示数据,否则关闭该延迟框...

有调用到数据时如图:

 

 

 无调用到数据时如图:

 

 脚本中的Ajax跟后台的关系如下: 

 

(3)弹出层虽然调出来了,但是我们还是不能对它进行操作,因此我们在再写三个js函数sel、unsel、clickS,分别是鼠标经过,离开和点击弹出层对应行的时候执行的操作,

         这三个js函数我们在WebService中有相应调用...

 

代码
 
   
// 鼠标经过函数
function sel(ids)
{
$(
" # " + ids).css( " background-color " , " #e2eaff " );
}

// 鼠标离开函数
function unsel(ids)
{
$(
" # " + ids).css( " background-color " , " #ffffff " );
}

// 鼠标点击时执行的事件
function clickS(ids)
{
$(
" #txtSearch " ).val($( " # " + ids + " B " ).html());
$(
" #searchDiv " ).remove();
}

 

 

 效果如下:

当鼠标移至相应行,相应行的背景色变化,并将该行的数据填充到搜索框...

 

 

点击相应行,执行查询

 

 

 (5)使用键盘的上下键进行操作(这样,当鼠标向上或向下的时候就可以执行相应的行选择)

脚本如下:

 

代码
 
   
pointRow =- 1 ; // 用以获取和设置位置指标,全局变量

$(document).keyup(
function (event){
var len = $( " #searchDiv p " ).length; // 获取自动搜索的行数

// 键盘向上键触发的事件,向上键在keyCode中的代码为38
if (event.keyCode == " 38 " )
{
if (pointRow ==- 1 )
{
pointRow
= len - 1 ;
$(
" #searchDiv p " ).eq(pointRow).css( " background-color " , " #e2eaff " ); // 如果是首次载入,向上键指向最后一行,背景色变化
$( " #txtSearch " ).val($( " #searchDiv p " ).eq(pointRow).children( " B " ).html()); // 将选中的行的内容填充进搜索框
}
else
{
$(
" #searchDiv p " ).eq(pointRow).css( " background-color " , " #ffffff " ); // 去掉背景色
if (pointRow == 0 ) pointRow = len - 1 ; else pointRow = pointRow - 1 ; // 判断,如果到顶了,则跳到最后一行重新开始
$( " #searchDiv p " ).eq(pointRow).css( " background-color " , " #e2eaff " ); // 指向上一行数据
$( " #txtSearch " ).val($( " #searchDiv p " ).eq(pointRow).children( " B " ).html()); // 并将选中的行的内容填充进搜索框
}
}

// 键盘向下键触发的事件,该键在keyCode中的代码为40
if (event.keyCode == " 40 " )
{
if (pointRow ==- 1 )
{
pointRow
= 0 ;
$(
" #searchDiv p " ).eq(pointRow).css( " background-color " , " #e2eaff " ); // 如果是首次载入,向下键指向第一行,背景色变化
$( " #txtSearch " ).val($( " #searchDiv p " ).eq(pointRow).children( " B " ).html()); // 将选中的行的内容填充进搜索框
}
else
{
$(
" #searchDiv p " ).eq(pointRow).css( " background-color " , " #ffffff " ); // 去掉背景色
if (pointRow == len - 1 ) pointRow = 0 ; else pointRow = pointRow + 1 ; // 判断,如果到尾了,则跳到第一行重新开始
$( " #searchDiv p " ).eq(pointRow).css( " background-color " , " #e2eaff " ); // 指向下一行数据
$( " #txtSearch " ).val($( " #searchDiv p " ).eq(pointRow).children( " B " ).html()); // 并将选中的行的内容填充进搜索框
}
}

})

 

这时候,我们在form中这样设置

<form id="form1" runat="server" defaultbutton="btnSearch">

其实就是定义了回车键的默认控件,所以当我们确认要执行的数据时,我们按下Enter键,功效跟点击btnResearch是一样的,即执行查询...

  

设计小结:

时间紧迫,脚本写的很粗糙,当总归是实现了,在写这个设计时候,遇到了一个问题,就是keyup冲突,所以我上面把它们分开,分别有$(Document).keyup

和 $("#txtResearch").keyup,一个用来上下选择,一个用来键入搜索内容的...其实可以解决的,但是我比较懒,所以就不去深究了...

之前有看了一下百度的实现方法,它是在下面追加 一个table。然后每个搜索条目用一个<tr>来装,百度这样处理相对样式好控制,反正比我这高明多了,有兴趣也可以去看一下...

 

后台我采用xml来存取数据,还写了个添加数据的页面,这样相对于简单,如果用SQl,附件一传上来就好大,太占空间了... 

最终实现如下:

 

 

点击下载源码(http://files.cnblogs.com/wzh2010/AjaxSearch.rar

 

转载于:https://www.cnblogs.com/wzh2010/archive/2010/11/06/1870502.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值