
写在前面
今天周六,我又来分享知识啦。最近一直在忙项目,所以趁着这个周末,喝着咖啡,听着音乐,敲着代码就把做项目的知识点总结给大家,简直不要太惬意,哈哈。
先从我做的功能界面开始说起:

本篇主要介绍的就是图中红框标记的搜索自动匹配功能。仔细想一想,有木有很熟悉,对,这功能其实就是跟你每天百度、谷歌这样的搜索功能一样。所以下面我会分享一些知识点并写个例子来实现这样的功能。
每天都用到的搜索自动匹配功能
百度的搜索框(默认显示四条数据)

美团搜索框

淘宝搜索框

首先,大概过程肯定是这样的:先从输入框中输入关键字,然后根据关键字在缓存或数据库取数据返回显示在下方区域。
重点知识汇总
要实现此功能,JQuery+ajax是必备。这个功能需要服务端配合。客户端通过ajax从服务端取得的数据。下面,我写个简书搜索自动匹配的例子,数据是事先定义好在脚本里的,当然,如果我有访问简书数据库的权限和账号密码,就可以动态的获取实时数据了。
开始之前,先给大家普及一下例子中用到的重点知识。
知识点一
keydown(function(e){}
这个keydown函数是当按下按键时触发事件,比如改变文本域的颜色。
比如这段代码:
<html>
<head>
<script type="text/javascript" src="/jquery/jquery.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$("input").keydown(function(){
$("input").css("background-color","#FFFFCC");
});
$("input").keyup(function(){
$("input").css("background-color","#D6D6FF");
});
});
</script>
</head>
<body>
Enter your name: <input type="text" />
<p>当发生 keydown 和 keyup 事件时,输入域会改变颜色。请试着在其中输入内容。</p>
</body>
</html>

变量e表示发生击键事件,寻找是哪个键被按下,要使用which这个属性。
知识点二
var keycode = e.which ? e.which : e.keyCode;
这句代码是为了兼容浏览器按键事件对象的按键码属性, 如IE中,只有keyCode属性,而FireFox中有which和charCode属性,Opera中有keyCode和which属性等。
知识点三
if(keycode == 38){}
常用按键码与按键关系对应表

知识点四
onKeyUp 事件:onkeyup 事件会在键盘按键被松开时发生。
知识点五
blur() 方法:当失去焦点 (blur) 时触发事件,比如输入域失去焦点改变其颜色。
removeClass() 方法:从被选元素移除一个或多个类。
addClass()方法:向被选元素添加一个或多个类。
整体思路及完整代码:
首先在输入框上注册keyup事件,然后在事件中获取我实现定义的data对象数组(一般实时数据通过ajax获取json对象)。取得数据后,在下方区域就可以显示数据了,当我们点击每一项的时候,就可以响应事件。同时根据索引值来调整背景高亮。
html代码:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>简书自动搜索功能例子</title>
<meta name="Author" content="wblearn">
<meta name="Keywords" content="http://www.jianshu.com/users/48599dc7ef1b/latest_articles">
<meta name="Description" content="简书自动搜索功能例子">
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" media="all" href="http://cdn-qn0.jianshu.io/assets/base-00828532d00225531ad20ff45bf311ea.css">
<link rel="stylesheet" media="all" href="http://cdn-qn0.jianshu.io/assets/reading-note-31f4bce318acdaac0a693701a57737e3.css">
<link rel="stylesheet" media="all" href="http://cdn-qn0.jianshu.io/assets/base-read-mode-5f4051bc94fc595e8bc00821aae6c3e1.css">
<script type="text/javascript" src="http://code.jquery.com/jquery-1.8.3.js"></script>
<script src="http://cdn-qn0.jianshu.io/assets/modernizr-613ea63b5aa2f0e2a1946e9c28c8eedb.js"></script>
<style type="text/css">
#container{
position:absolute;
left:50%;
top: 40%;
}
#content{
float:left;
position:relative;
right:50%;
}
input{
border:0;
width:288px;
height:30px;
font-size:16px;
padding:0 5px;
line-height:30px;
}
.item{
padding:3px 5px;
cursor:pointer;
}
.addbg{
background:#87A900;
}
.first{
border:solid #87A900 2px;
width:300px;
}
#append{
border:solid #87A900 2px;
border-top:0;
display:none;
}
img {
max-width: 100%;
width: 40px;
height: 40px;
vertical-align: middle;
border: 0;
-ms-interpolation-mode: bicubic;
}
font{
margin-left: 20px;
margin: 10px 0;
font-family: inherit;
font-weight: bold;
line-height: 20px;
color: inherit;
text-rendering: optimizelegibility;
}
</style>
</head>
<body>
<div id="container">
<div id="content">
<div class="first"><input id="kw" onKeyup="getContent(this);" /></div>
<div id="append"></div>
</div>
</div>
</body>
</html>
js代码:
<script type="text/javascript">
var data = [
""+" <font>简书IT·互联网专题</font>",
""+" <font>简书IT·互联网主编: 向右奔跑</font>",
""+" <font>简书程序员专题</font>",
""+" <font>简书程序员主编: 小彤花园</font>",
""+" <font>简书连载小说专题</font>",
""+" <font>简书连载小说主编: 一鸣</font>",
""+" <font>简书诗专题</font>",
""+" <font>简书诗主编:北海源</font>",
""+" <font>简书其他专题</font>",
""+" <font>简书其他主编</font>"
];
$(document).ready(function(){
$(document).keydown(function(e){
e = e || window.event;
var keycode = e.which ? e.which : e.keyCode;
if(keycode == 38){
if(jQuery.trim($("#append").html())==""){
return;
}
movePrev();
}else if(keycode == 40){
if(jQuery.trim($("#append").html())==""){
return;
}
$("#kw").blur();
if($(".item").hasClass("addbg")){
moveNext();
}else{
$(".item").removeClass('addbg').eq(0).addClass('addbg');
}
}else if(keycode == 13){
dojob();
}
});
var movePrev = function(){
$("#kw").blur();
var index = $(".addbg").prevAll().length;
if(index == 0){
$(".item").removeClass('addbg').eq($(".item").length-1).addClass('addbg');
}else{
$(".item").removeClass('addbg').eq(index-1).addClass('addbg');
}
}
var moveNext = function(){
var index = $(".addbg").prevAll().length;
if(index == $(".item").length-1){
$(".item").removeClass('addbg').eq(0).addClass('addbg');
}else{
$(".item").removeClass('addbg').eq(index+1).addClass('addbg');
}
}
var dojob = function(){
$("#kw").blur();
var value = $(".addbg").text();
$("#kw").val(value);
$("#append").hide().html("");
}
});
function getContent(obj){
var kw = jQuery.trim($(obj).val());
if(kw == ""){
$("#append").hide().html("");
return false;
}
var html = "";
for (var i = 0; i < data.length; i++) {
if (data[i].indexOf(kw) >= 0) {
html = html + "<div class='item' onmouseenter='getFocus(this)' onClick='getCon(this);'>" + data[i] + "</div>"
}
}
if(html != ""){
$("#append").show().html(html);
}else{
$("#append").hide().html("");
}
}
function getFocus(obj){
$(".item").removeClass("addbg");
$(obj).addClass("addbg");
}
function getCon(obj){
var value = $(obj).text();
$("#kw").val(value);
$("#append").hide().html("");
}
</script>
写在最后
以上就是我总结分享搜索自动匹配功能的全部内容,当然,界面我还可以做得更美观,功能可以做的更完善。今天先到这里,下次见(持续更新中......)
网友评论
可是一个孤零零、没有提示的搜索框,反而给用户带来无助感:很多时候用户不知道要输入些什么
为什么不能像baidu、淘宝、google那样,给搜索框添加一个自动提示(自动补全)功能呢,
对用户而言,可以有效降低输入成本,获得更多提示,快速了解网站的优质资源
对站长而言,可以优先推送网站的优质关键信息,等于多了一个广告位,更多的展示网站优先推荐的内容。
最近做了一个搜索项目,
发现很多用户会偷懒,直接输入拼音、拼音首字母、某个词汇去进行搜索,
在此情况下,
为网站的搜索框安装一个类似百度、google那样的搜索提示、补全功能。
要求系统能快速响应用户的搜索需求;
同时还发现,不同的用户对同一个词条(标题)的提示排序顺序,有不同要求,
比如输入jd,高校图书馆用户希望《基督山伯爵》排在前面,《京东疯狂大减价》(我YY的)排在后面,
如果是电商,正好相反,对电商而言,不同销售季节,希望搜索提示出词条的排序也是不同的。
我发现在网上找个关于搜索框(input标签)自动提示的JS插件很容易,一大堆供你挑选,
但是,要想实现拼音、拼音首字母匹配、模糊匹配、智能容错、自定义提示词条自主排序等等这些功能,
是非常琐碎非常麻烦的,
更麻烦的是,我的数据在50万条左右,要想前端用户输入之后有较快(延时小于100ms)的响应,
还需要在前端加一层cache,memocache 、redis试了个遍。
网上的智能提示JS插件,都仅仅是一个前端界面,要实现自动提示,最大困难的是后端实现
92find做一个这样的JS插件:
把前面提到那些功能都封装起来,放在一台云服务器上,
开发者每次需要使用自动提示这个功能时,
只需准备好要提示的词条列表或者标题列表,及其排序的优先级,
向云服务器提交这些数据,服务自动生成前面提到的各种索引(前缀、拼音、容错),
并且自动分发到一个cache中,
开发者只需在自己的H5页面(或者普通HTML页面)中引用一行JS代码,
就可以通过跨域的方式使用自动提示的数据了,
不再需要配置什么数据库,也不需要写一行后台的java/php代码
只需5分钟 和一个txt文本,
自己的搜索框提示功能就上线了,同baidu、淘宝一样强大。
我把这个功能安装在了国内几家211、985大学的网站上
项目网站www.92find.com
如果数据量大还需要特殊优化,一个小功能,花费太大精力不合适
但这是个可有可无的功能吗,肯定不是
对用户而言,可以有效降低输入成本,在面对输入框时,获得更多提示,不用那么迷茫和无助
对站长而言,可以优先推送网站的关键信息,等于多了一个广告位。
一所大学图书馆的搜索框智能提示,大约50万个词条(书名)
他们使用的是www.92find.com的搜索框智能提示免费产品,
只要一行javascript代码,就可以实现baidu、淘宝搜索框提示的全部功能
比如:拼音匹配、拼音首字母匹配、模糊搜索、智能容错,
还可以自定义提示词汇及其排序权重
你只需要准备好自己的提示词汇表就可以了,
无需编写程序,
五分钟(真的是5分钟)就可以在线配置拥有
主流搜索引擎都有的自动提示(自动补全)功能