Servlet+Ajax实现搜索智能提示

Posted 舒山

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Servlet+Ajax实现搜索智能提示相关的知识,希望对你有一定的参考价值。

一般在百度搜索框输入关键词时,会弹出一些相关信息提示,方便点选:

页面(search.jsp):

1 <input type="text"  name="keyWords" id="keyWords"  style="width:200px; height:20px;"  /> 
2 <input type="button" id="button" value="百度一下">
html

创建新的div层,用以放置获取到的提示内容:

 1     <div>
 2         <input type="text"  name="keyWords" id="keyWords" style="width:200px; height:20px;" /> 
 3                 <input type="button" id="button" value="百度一下">
 4             <div id="popDiv">
 5             <table id="content_table">
 6                 <tbody id="content_table_body">
 7                 </tbody>
 8             </table>
 9         </div>
10     </div>
HTML

创建XMLHttpRequest对象:

 1     function createXmlHttp()
 2     {
 3         var xmlHttp;
 4         //创建XMLHttpRequest
 5         if(window.XMLHttpRequest)
 6             {
 7             xmlHttp = new XMLHttpRequest();
 8             //兼容某些Mozilla浏览器的响应头,强制设置为text/xml,具体参看:http://www.cnblogs.com/perseverancevictory/p/3690769.html
 9                if(xmlHttp.overrideMimeType){  
10                    xmlHttp.overrideMimeType("text/xml");  
11                }
12             }
13         //兼容IE
14         else if(window.ActiveXObject)
15             {
16             xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
17             if(!xmlHttp)
18                 {
19                 xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
20                 }
21             }
22         return xmlHttp;
23     }
javascript

当输入时出现提示,因此需要在input框中添加onkeyup事件,用以获取相关提示:

1 <input type="text"  name="keyWords" id="keyWords"  style="width:200px; height:20px;" onkeyup="getMoreContens()" />
HTML

实现onkeyup事件:

 1         var xmlHttp;
 2     //获取用户输入的关联信息的函数
 3     function getMoreContens() {
 4         //获取用户输入
 5         var content = document.getElementById("keyWords").value;
 6         if (content == "") {
 7             clearContent();
 8             return;
 9         }
10         xmlHttp = createXmlHttp();
11         //给服务器发送数据
12         var url = "search?keyword="+encodeURI(content); 
13         xmlHttp.open("GET",url,true);
14         xmlHttp.onreadystatechange =     //回调函数
15             function callback()
16         {
17             if(xmlHttp.readyState == 4)
18                 {
19                 if(xmlHttp.status == 200){
20                     var result = decodeURIComponent(xmlHttp.responseText);
21                     var json = eval("("+result+")");
22                     clearContent(json);
23                     intelliSense(json);
24                 }
25                 }
26         };
27         /*
28             xmlhttp的send是传递参数用的,但是只有在使用post方式提交请求的时候才有用
29             如下:
30             xmlhttp.open("post",url,true); 
31             ...
32             xmlhttp.send("data=data&data2=data2");
33              
34             用get的话一般就是:
35             xmlhttp.open("get",url,true); 
36             ...
37             xmlhttp.send(null);
38         */
39         xmlHttp.send(null);
40     }
javascript

可以看到,getMoreConten()方法中有clearContent()和intelliSense(json)两个自定义方法,它们的作用分别是清空提示和根据输入智能获取关键字,实现如下:

intelliSense(获取智能提示并放置在输入框下方table中):

 1     function intelliSense(json)
 2     {
 3         //获取关联数据的长度
 4         var size = json.length;
 5         for(var i=0;i<size;i++)
 6             {
 7             var nextNode = json[i];
 8             var tr= document.createElement("tr");
 9             var td= document.createElement("td");
10             tr.setAttribute("border", "0");
11             tr.setAttribute("bgcolor", "#EDEDED");
12             td.setAttribute("width", "200px");
13             td.onmouseover=function()
14             {
15                 this.className = \'mouseOver\';
16             }
17             td.onmouseout=function()
18             {
19                 this.className = \'mouseOut\';
20             }
21             td.onclick=function()
22             {
23                 document.getElementById("keyWords").value=this.innerText;
24             }
25             var text=document.createTextNode(nextNode);
26             td.appendChild(text);
27             tr.appendChild(td);
28             document.getElementById("content_table_body").appendChild(tr);
29             }
30     }
javascript

clearContent:

1     function clearContent()
2     {
3         var contentTableBody = document.getElementById("content_table_body");
4         var size = contentTableBody.childNodes.length;
5         for(var i=size-1;i>0;i--)
6             {
7             contentTableBody.removeChild(contentTableBody.childNodes[i]);
8             }
9     }
javascript

页面上基本完成,接下来需要实现getMoreContens方法中定义的名叫search的Servlet:

在web.xml中配置:

1 <servlet-mapping>
2     <servlet-name>search</servlet-name>
3     <url-pattern>/search</url-pattern>
4 </servlet-mapping>
5 <servlet>
6     <description>搜索</description>
7     <servlet-name>search</servlet-name>
8     <servlet-class>com.yan.search.SearchServlet</servlet-class>
9 </servlet> 
xml

Servlet实现:

 1 private static List<String> keyWordList = new ArrayList<String>();
 2     static {
 3         // 模拟数据
 4         keyWordList.add("yanwei");
 5         keyWordList.add("yantian");
 6         keyWordList.add("yanpeng");
 7         keyWordList.add("yanweichao");
 8         keyWordList.add("yanweiqi");
 9         keyWordList.add("yanyurong");
10         keyWordList.add("yanmeirong");
11         keyWordList.add("yanweichen");
12         keyWordList.add("电影");
13         keyWordList.add("电影 66ys");
14     }
15     private static final long serialVersionUID = 1L;
16 
17     @Override
18     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
19             throws ServletException, IOException {
20         doGet(req, resp);
21     }
22 
23     @Override
24     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
25             throws ServletException, IOException {
26 
27         String keyWord = req.getParameter("keyword");
28         System.out.println(keyWord);
29         List<String> list = keyWord==null?new ArrayList<String>():getDatas(keyWord);
30         String json = JSON.toJSONString(list);
31         //防止乱码
32         String encodeJSON = URLEncoder.encode(json,"UTF-8");
33         resp.getWriter().write(encodeJSON);
34     }
35 
36     public static List<String> getDatas(String keyWord) {
37         List<String> list = new ArrayList<String>();
38         for (int i = 0; i < keyWordList.size(); i++) {
39             if (keyWordList.get(i).contains(keyWord)) {
40                 list.add(keyWordList.get(i));
41             }
42         }
43         return list;
44     }
Java

此时基本功能已经实现,但还有一些小细节需要处理:

1.当文本框失去焦点时,提示应该消失

在输入框属性中添加onblur事件,触发clearContent方法;

2.获得焦点时再次出现提示

在输入框属性中添加onfocus事件,触发intelliSense方法;

3.当鼠标滑过载有提示信息的table时,应加一些样式显得更友好:

我们在intelliSense方法中已经为td元素设置了类名mouseOver和mouseOut,因此添加css样式即可:

1 .mouseOver {
2     background: #00B2EE;
3     color: white;
4     width: 200px;
5 }
6 .mouseOut {
7     background: #EDEDED;
8     width: 200px;
9 }
CSS

呈现效果:

最终代码:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app id="WebApp_ID" version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 3 <welcome-file-list>
 4     <welcome-file>index.jsp</welcome-file>
 5 </welcome-file-list>
 6 <servlet-mapping>
 7     <servlet-name>search</servlet-name>
 8     <url-pattern>/search</url-pattern>
 9 </servlet-mapping>
10 <servlet>
11     <description>搜索</description>
12     <servlet-name>search</servlet-name>
13     <servlet-class>com.yan.search.SearchServlet</servlet-class>
14 </servlet> 
15 </web-app>
web.xml

 

  1 <%@ page language="java" contentType="text/html; charset=UTF-8"
  2     pageEncoding="UTF-8"%>
  3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  4 <html>
  5 <head>
  6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  7 <title>smart search</title>
  8 <style type="text/css">
  9 .mouseOver {
 10     background: #00B2EE;
 11     color: white;
 12     width: 200px;
 13 }
 14 .mouseOut {
 15     background: #EDEDED;
 16     width: 200px;
 17 }
 18 </style>
 19 <script type="text/javascript">
 20         var xmlHttp;
 21     //获取用户输入的关联信息的函数
 22     function getMoreContens() {
 23         //获取用户输入
 24         var content = document.getElementById("keyWords").value;
 25         if (content == "") {
 26             clearContent();
 27             return;
 28         }
 29         xmlHttp = createXmlHttp();
 30         //给服务器发送数据
 31         var url = "search?keyword="+encodeURI(content); 
 32         xmlHttp.open("GET",url,true);
 33         xmlHttp.onreadystatechange =     //回调函数
 34             function callback()
 35         {
 36             if(xmlHttp.readyState == 4)
 37                 {
 38                 if(xmlHttp.status == 200){
 39                     var result = decodeURIComponent(xmlHttp.responseText);
 40                     var json = eval("("+result+")");
 41                     clearContent(json);
 42                     intelliSense(json);
 43                 }
 44                 }
 45         };
 46         /*
 47             xmlhttp的send是传递参数用的,但是只有在使用post方式提交请求的时候才有用
 48             如下:
 49             xmlhttp.open("post",url,true); 
 50             ...
 51             xmlhttp.send("data=data&data2=data2");
 52              
 53             用get的话一般就是:
 54             xmlhttp.open("get",url,true); 
 55             ...
 56             xmlhttp.send(null);
 57         */
 58         xmlHttp.send(null);
 59     }
 60     
 61     //创建XMLHttpRequest
 62     function createXmlHttp()
 63     {
 64         var xmlHttp;
 65         if(window.XMLHttpRequest)
 66 以上是关于Servlet+Ajax实现搜索智能提示的主要内容,如果未能解决你的问题,请参考以下文章

原生AJAX+jsp+servlet实现百度搜索框提示效果

AJAX实现搜索智能提示

百度下拉智能搜索提示

使用jsonp跨域调用百度js实现搜索框智能提示,并实现鼠标和键盘对弹出框里候选词的操作附源码和在线测试地址

Ajax-Servlet第二课 员工管理系统-二级联动搜索功能

通过ajax调用servlet下载文件。