[转载]使用jQuery.AutoComplete完成仿淘宝商品搜索功能(改进了键盘上下选择体验)

[转载]使用jQuery.AutoComplete完成仿淘宝商品搜索功能(改进了键盘上下选择体验) – kyo-yo – 博客园.

其实这个已经是个比较常见的功能了,网上也有很多人做过这个了,但是很多都是仅仅做了一些基本的网页上自动完成功能,没有与具体的数据库进行联动,我今天所介绍这个自动完成的就是我修改的JQuery.AutoComplete+数据库的一个解决方案

首先来看一些效果图:

pic1

这个是淘宝首页的搜索效果

pic3

京东首页的搜索效果

pic2

我修改的jQuerzy.AutoComplete实现的效果

一、实现效果分析

我要实现的效果就是和GOOGLE类似,需要满足一下3个要求(因为这样我认为是最好的用户体验,毕竟GOOGLE做了那么久了):

1、首先根据关键字列出关键字相关的信息(包含统计信息)

2、可以使用键盘上下键选择(默认不选中第一条),文本框内容根据选择信息变换

3、当选择第一或者最后一条时再向上或向下则取消选中,文本框中内容还原回原先输入的内容(这点比较重要,京东这个就做不好,因为当在向上向下选择的过程中因为文本框内容会跟着换,所以就无法还原到当初用户所输入的内容了)

二、具体实现分析

首先呢因为具体数据时来自于数据库,所以首先在数据库中建立张表用于存放搜索历史记录,每次用户查询的其实就是数据库中的表的记录(也就是上次查询这个关键字的记录数)

1 CREATE TABLE [dbo].[t_KeywordSearchHistory] (
2 [Keyword] [nvarchar] (128) primary key, --关键字
3 [Count] [int] NOT NULL , --搜索次数
4 [RecordCount] [int] NOT NULL --符合关键字的记录数
5 )

上面的表仅仅用于存放用户搜索的关键字,然后在搜索的存储过程或者SQL语句中才进行相应的处理,当用户在页面上输入完关键字然后再点击搜索此时需 要首先根据关键字在数据库中检索相应的数据,若此关键字有相关数据则向t_KeywordSearchHistory表新增一条数据(若此表中已有此关键 字则更新搜索次数和符合关键字的记录数)

01 --上面的是具体的SQL查询代码(统计符合关键字的商品数量
02 if @recordCount>0
03 begin
04 if @keyword <>''
05 begin
06 if exists (select keyword from t_KeywordSearchHistory where keyword=@keyword)
07 begin
08 update t_KeywordSearchHistory set
09 Count=Count+1,
10 RecordCount=@recordCount
11 where keyword=@keyword
12 end
13 else
14 begin
15 insert into t_KeywordSearchHistory values(@keyword,1,@recordCount)
16 end
17 end
18 end
19 else
20 begin
21 update t_KeywordSearchHistory set Count=Count+1,
22 RecordCount=@recordCount
23 where keyword=@keyword
24 end

完成了数据库方面的相关代码后就是界面上的,首先是JQuery.AutoComplete的调用方法:

1 JQuery(function(){
2 jQuery("#txtKeyword").autocomplete("<%=Me.Page.ResolveClientUrl("~/Service.asmx/AutoComplete") %>", {
3 httpMethod: "POST", //使用POST调用WebService
4 dataType: 'xml',//返回数据类型为XML
5 minchar: 1,//最小响应字符数量
6 selectFirst:false,//默认不选中第1条
1 //格式化选项,由于WebService返回的数据是JSON格式,现在要转成HTML以TABLE形式显示
2 formatItem:function(row,i,max){
1 var obj=eval("("+row+")");//将JSON转换成对象
2 var item="<table id='auto"+i+"' style='width:100%;'>
3 <tr>
4 <td align='left'>"+obj.value+"</td>
5 <td align='right' style='color:green;'>"+obj.num+"</td>
6 </tr>
7 </table>";
8 return item;
9 },
1 //格式化结果,当选中时返回具体的值
2 formatResult:function(row,i,max){
3 var obj=eval("("+row+")");
4 return obj.value;
5 }
6 });
7 });

WebService代码:

1 [WebMethod()]
2 public string[] GetGoodsAutoComplete(string q)
3 {
4 List<string> list = new List<string>();
01 //JSON格式模板,同时以换行符分隔,在JS脚本中会进行处理
02 string template = "{{value:'{0}',num:'{1}'}}" + System.Environment.NewLine;//+”\n”
03 SqlCommand cmd = new SqlCommand();
04 SqlDataReader reader = null;
05 cmd.CommandText = "GetAutoComplete";
06 cmd.CommandType = CommandType.StoredProcedure;
07 cmd.Parameters.Add("@keyword", SqlDbType.NVarChar, 128).Value = q;
08 try {
09 reader = Tools.Data.SQLServerHelper.GetReader(VolkHelper.GetDBConnString(), cmd);
10 if (reader != null) {
11 while (reader.Read()) {
12 string s = string.Format(template, (string)reader["keyword"], "约" + (string)reader["num"] + "件商品");
13 list.Add(s);
14 }
15 }
16 }
17 catch (Exception ex) {
18
19 }
20 return list.ToArray();
21 }

接下来就是我修改的jQuery.AutoComplete.js,由于代码太长,我在文章最后已经加了下载的链接所以就不把代码全部贴出来了,仅贴我修改的地方:

1 function moveSelect(step) {
2 listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
3 movePosition(step);
4 var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
5 //当动作对象为空时还原用户输入的值
01 if (activeItem[0] != null || activeItem[0] != undefined) {
02 input.value = jQuery(activeItem[0]).find("td:first").text();
03 }
04 if (active >= 0) {
05 if (options.scroll) {
06 var offset = 0;
07 listItems.slice(0, active).each(function() {
08 offset += this.offsetHeight;
09 });
10 if ((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
11 list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
12 } else if (offset < list.scrollTop()) {
13 list.scrollTop(offset);
14 }
15 }
16 }
17 };
18
19 function movePosition(step) {
20 if (active < 0 && step == -1) {
21 active = listItems.size()-1;
22 return;
23 }
24 active += step;
1 //光标不再列表时还原用户输入的值
2 if (active < 0) {
3 active = -1;
4 input.value = oldValue;
5 return;
6 }
7 //超出关键字列表时还原用户输入的值
1 if (active >= listItems.size()) {
2 active = -1;
3 input.value = oldValue;
4 return;
5 }
6 }

已经684行开始:

01 next: function() {
02 if (active == -1) {
03 oldValue = input.value;//一开始将用户输入的值存入一个指定的变量
04 }
05 moveSelect(1);
06 },
07 prev: function() {
08 if (active == -1) {
09 oldValue = input.value;
10 }
11 moveSelect(-1);
12 },

以上就完成了自动完成的全部的必须条件了,如果对jQuery.Autocomplete不熟悉的话可以去这里看下具体的使用方法。我在这就不详细说明了。

有网友反映jQuery.AutoComplete无法调试成功,本来在写文章中忘了注明了,就是在webservice中需要添加这个配置节:

01 在system.web配置节下添加:
02 <!--webservice设置-->
03 <webServices>
04 <protocols>
05 <add name="HttpPost"/>
06 <!--<add name="HttpGet"/>
07 <add name="HttpSoap"/>
08 <add name="Documentation"/>-->
09 </protocols>
10 </webServices>

同时在webservice中需要为webservice中添加以下特性:

1 [System.Web.Script.Services.ScriptService()]
2 [WebService(Namespace = http://tempuri.org/)]
3 [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]

其中[System.Web.Script.Services.ScriptService()]特性需要VS2008才拥有,否则是无法调试成功的

附我修改的jQuery.AutoComplete.rar下载:点我下载

PS:大家如果觉得好帮忙点下推荐,谢谢大家了!

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏