asp.net下使用jQuery.AutoComplete完成仿淘宝商品搜索自动完成功能(改进了键盘上下选择体验)

  首先来看一些效果图:

asp.net下使用jQuery.AutoComplete完成仿淘宝商品搜索自动完成功能(改进了键盘上下选择体验)

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

asp.net下使用jQuery.AutoComplete完成仿淘宝商品搜索自动完成功能(改进了键盘上下选择体验)

京东首页的搜索效果

asp.net下使用jQuery.AutoComplete完成仿淘宝商品搜索自动完成功能(改进了键盘上下选择体验)

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

  一、实现效果分析

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

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

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

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

  二、具体实现分析

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

  

复制代码 代码如下:
CREATE TABLE [dbo].[t_KeywordSearchHistory] (

  [Keyword] [nvarchar] (128) primary key, --关键字

  [Count] [int] NOT NULL , --搜索次数

  [RecordCount] [int] NOT NULL --符合关键字的记录数

  )

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

  

复制代码 代码如下:

  --上面的是具体的SQL查询代码(统计符合关键字的商品数量

  if @recordCount>0

  begin

  if @keyword <>''

  begin

  if exists (select keyword from t_KeywordSearchHistory where keyword=@keyword)

  begin

  update t_KeywordSearchHistory set

  RecordCount=RecordCount+1,

  RecordCount=@recordCount

  where keyword=@keyword

  end

  else

  begin

  insert into t_KeywordSearchHistory values(@keyword,1,@recordCount)

  end

  end

  end

  else

  begin

  update t_KeywordSearchHistory set Count=Count+1,

  RecordCount=@recordCount

  where keyword=@keyword

  end

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

  

复制代码 代码如下:
jQuery(function(){

  jQuery("#txtKeyword").autocomplete("<%=Me.Page.ResolveClientUrl("~/Service.asmx/AutoComplete") %>", {

  httpMethod: "POST", //使用POST调用WebService

  dataType: 'xml',//返回数据类型为XML

  minchar: 1,//最小响应字符数量

  selectFirst:false,//默认不选中第1条

  //格式化选项,由于WebService返回的数据是JSON格式,现在要转成HTML以TABLE形式显示

  formatItem:function(row,i,max){

  var obj=eval("("+row+")");//将JSON转换成对象

  var item="<table id='auto"+i+"' style='width:100%;'>

  <tr>

  <td align='left'>"+obj.value+"</td>

  <td align='right' style='color:green;'>"+obj.num+"</td>

  </tr>

  </table>";

  return item;

  },

  //格式化结果,当选中时返回具体的值

  formatResult:function(row,i,max){

  var obj=eval("("+row+")");

  return obj.value;

  }

  });

  });

  WebService代码:

  

复制代码 代码如下:
[WebMethod()]

  public string[] GetGoodsAutoComplete(string q)

  {

  List<string> list = new List<string>();

  view sourceprint?01 //JSON格式模板,同时以换行符分隔,在JS脚本中会进行处理

  string template = "{{value:'{0}',num:'{1}'}}" + System.Environment.NewLine;//+”\n”

  SqlCommand cmd = new SqlCommand();

  SqlDataReader reader = null;

  cmd.CommandText = "GetAutoComplete";

  cmd.CommandType = CommandType.StoredProcedure;

  cmd.Parameters.Add("@keyword", SqlDbType.NVarChar, 128).Value = q;

  try {

  reader = Tools.Data.SqlServerHelper.GetReader(VolkHelper.GetDBConnString(), cmd);

  if (reader != null) {

  while (reader.Read()) {

  string s = string.Format(template, (string)reader("keyword"), "约" + (string)reader("num") + "件商品");

  list.Add(s);

  }

  }

  }

  catch (Exception ex) {

  }

  return list.ToArray();

  }

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

  

复制代码 代码如下:
function moveSelect(step) {

  listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);

  movePosition(step);

  var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);

  //当动作对象为空时还原用户输入的值

  if (activeItem[0] != null || activeItem[0] != undefined) {

  input.value = jQuery(activeItem[0]).find("td:first").text();

  }

  if (active >= 0) {

  if (options.scroll) {

  var offset = 0;

  listItems.slice(0, active).each(function() {

  offset += this.offsetHeight;

  });

  if ((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {

  list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());

  } else if (offset < list.scrollTop()) {

  list.scrollTop(offset);

  }

  }

  }

  };

  function movePosition(step) {

  if (active < 0 && step == -1) {

  active = listItems.size()-1;

  return;

  }

  active += step;

  //光标不再列表时还原用户输入的值

  if (active < 0) {

  active = -1;

  input.value = oldValue;

  return;

  }

  //超出关键字列表时还原用户输入的值

  if (active >= listItems.size()) {

  active = -1;

  input.value = oldValue;

  return;

  }

  }

  已经684行开始:

  

复制代码 代码如下:
next: function() {

  if (active == -1) {

  oldValue = input.value;//一开始将用户输入的值存入一个指定的变量

  }

  moveSelect(1);

  },

  prev: function() {

  if (active == -1) {

  oldValue = input.value;

  }

  moveSelect(-1);

  },

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

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