JS 实现搜索框智能提示

JS 实现搜索框智能提示

搜索框智能提示应用很广泛,从搜索引擎使用开始,被在各个平台使用

  • 搜索框输入内容,事件触发,ajax异步请求
  • 后台获取到ajax传来的参数,到数据库查询
  • 查询结果封装成json,返回
  • 前端获取返回的json字符串,格式化输出到页面

相关内容下载

Demo

数据库

word.js

ajax 异步请求

通过 keyup,focus 和 blur 动作组合,获取输入框内容,先查询本地缓存,如果存在缓存则直接读取,没有缓存就向后台发起 ajax 请求。

function getTranslation(keyword) {
    if(ajaxcache.has(keyword)){
      console.info("---从缓存中查询:"+keyword);
      var result = ajaxcache.get(keyword);
      if(jQuery.isEmptyObject(result)) return;
      $("#wordHint").empty().css("border", "1px solid #ccc");
      $.each(result, function(i, n) {
        $("#wordHint").append(
            "<div class=\"hintItem\">" + "<span class=\"hintItem_w\">" + n.w
              + "</span>" + "<span class=\"hintItem_t\" title=\""+ n.t +"\">" + n.t + "</span>"
              + "</div>");
      })
    }else {
      console.info("***从数据库查询:"+keyword);
      $.ajax({
        type : "POST",
        url : "/Dictionary/SearchServlet",
        data : "action=wordHint&word=" + keyword,
        dataType : "json",
        success : function(result) {
          ajaxcache.set(keyword, result);
          if(jQuery.isEmptyObject(result)) return;
          $("#wordHint").empty().css("border", "1px solid #ccc");
          $.each(result, function(i, n) {
            $("#wordHint").append(
                "<div class=\"hintItem\">" + "<span class=\"hintItem_w\">" + n.w
                    + "</span>" + "<span class=\"hintItem_t\" title=\""+ n.t +"\">" + n.t + "</span>"
                    + "</div>");
          })
        }
      })
    }
  }

后台根据请求参数查询数据库

后台使用 servlet 处理数据,获取参数到数据库查询,查询结果为空就返回空json串”[]”,查询到匹配结果后将结果封装为json串,返回到前端。json封装时没有使用流行的fastjson等方案,直接进行字符串拼接。

 if (list.size()< 1) {
        System.out.println("未找到结果");
        response.getWriter().write("[]");
      }else {
        StringBuilder sb = new StringBuilder();
        sb.append("[ ");
        for (Word w : list) {
          sb.append("{ ");
          sb.append("\"w\": \"");
          sb.append(w.getWord());
          sb.append("\" , ");
          sb.append("\"t\": \"");
          sb.append(w.getTranslation());
          sb.append("\" }, ");
        }
        String jsonStr = sb.toString().substring(0, sb.length() - 2) + " ]";
        System.out.println(jsonStr);
        response.getWriter().write(jsonStr);
 }

上下按键选择,鼠标移动选择

当有提示结果时,键盘上下键能够移动上下选择,鼠标悬停时也可以选取到结果。

var keycode = 'which' in e ? e.which : e.keyCode;
if (keycode == "40" || keycode == "38") {
  var current = hintCotainer.find(".hintItem.hover");
  if (keycode == "40") {
    if (current.length > 0) {
      var nextItem = current.removeClass("hover").next();
      if (nextItem.length > 0) {
        nextItem.addClass('hover');
        wordEl.val(nextItem.children(".hintItem_w").html());
      }
    } else {
      var firstItem = hintCotainer.find(".hintItem:first");
      firstItem.addClass("hover");
      wordEl.val(firstItem.children(".hintItem_w").html());
    }
  } else if (keycode == "38") {
    if (current.length > 0) {
      var prevItem = current.removeClass("hover").prev();
      if (prevItem.length > 0) {
        prevItem.addClass('hover');
        wordEl.val(prevItem.children(".hintItem_w").html());
      }
    } else {
      var lastItem = hintCotainer.find(".hintItem:last");
      lastItem.addClass("hover");
      wordEl.val(lastItem.children(".hintItem_w").html());
    }
  }
}

查询优化

优化问题主要在数据库查询上,通过设置请求延迟和本地缓存,减少不必要的数据库查询。

var timeout = 0;
clearTimeout(timeout);
timeout = setTimeout(function() {
  // 异步请求获取提示词
  var keyword = $.trim(wordEl.val());
  if (keyword == "" || keyword == null) {
    return;
  }
  getFuc(keyword);
},
200)
var ajaxcache = new Map();

if (ajaxcache.has(keyword)) {
  var result = ajaxcache.get(keyword);
} else {
  //ajax请求
}