一、功能需求
功能需求:
用户在搜索框中输入关键字,搜索框中出现下拉选项,显示关键字的提示语。
用户可以使用鼠标进行提示语的选择,也可以使用键盘的上下键来进行选择。
技术分析:
ajax+jsp+servlet+jdbc
功能分析(思路):
1.创建搜索界面(搜索框和提示语div和搜索按钮)
2.给搜索框添加onkeyup事件,键盘弹起时发送ajax请求
请求当前用户输入的信息相应提示语数据
3.将提示语数据填充到搜索框下的div数据中
4.实现使用鼠标选择提示语
5.实现使用键盘上下键选择
6.实现鼠标和键盘的联动操作
7.将显示语的div进行隐藏,当有提示语时显示隐藏的div
数据库设计:
1.创建表:(data) 储存常用的关键字数据
2.关键字编号:id
3.关键字数据:title
4.说明:remark
添加测试数据:
要求前期测试数据为英文单词
SQL语句设计:
查询以用户当前搜索框开头的文字
select * from data where title like ‘a%’
注意:提示语不要太多
数据库实现,在数据库中创建表,添加测试数据。
二、代码实现
1.数据库设计:
##创建关键字词汇表
create table t_data (
id int(10) not null auto_increment,
title varchar(100) not null,
remark varchar(500),
primary key(id)
)
##添加测试数据
insert into t_data values(default,'abc','');
insert into t_data VALUES(DEFAULT,'abb','');
insert into t_data VALUES(DEFAULT,'acc','');
insert into t_data VALUES(DEFAULT,'add','');
insert into t_data VALUES(DEFAULT,'bee','');
insert into t_data VALUES(DEFAULT,'bff','');
insert into t_data VALUES(DEFAULT,'abg','');
insert into t_data VALUES(DEFAULT,'abh','');
insert into t_data VALUES(DEFAULT,'crt','');
##查询所有数据
select * from t_data;
2.设计搜索框页面:
<body>
<!-- 创建div容器将搜索框和搜索框提示语div显示到一起 -->
<!-- 创建div进行搜索框布局 -->
<div id="container" style="width:550px;margin:auto;">
<div id="sdiv" style="width:550;margin:auto;margin-top:200px;">
<input name="search" type="text" id="search" style="width:400px;height:30px;font-size:18px;"/>
<input type="button" value="搜索" style="width:100px;height:30px;"/>
</div>
<!-- 提示语div -->
<div id="dataDiv" style="width:398px;height:300px;border:solid 1px;border-top:none;" ></div>
</div>
</body>
如图:
3.提示语后台功能实现
1)V层:
js代码:
<script type="text/javascript">
//页面加载成功,完成页面资源的初始化
$(function(){
//给搜索框添加键盘弹起事件
$("#search").keyup(function(){
//获取用户当前搜索框的数据
var sd=$("#search").val();
//发起ajax请求,请求当前用户搜索的提示信息
$.get("search",{sdata:sd},function(data){
//使用eval方法将数据转化为对象
eval("var sd="+data);
//获取提示语div元素对象
var dataDiv=$("#dataDiv");
//清空内容
dataDiv.empty();
//将提示语数据填充到div中
for(var i=0;i<sd.length;i++){
dataDiv.append("<div style='padding:5px;'>"+sd[i].title+"<div/>");
}
})
})
})
</script>
2)C层:
SearchServlet
package com.facai.servlet;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.facai.pojo.Data;
import com.facai.service.SearchService;
import com.facai.service.SearchServiceImpl;
import com.google.gson.Gson;
public class SearchServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
//设置请求编码格式
req.setCharacterEncoding("utf-8");
//设置响应编码格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String sdata=req.getParameter("sdata");
//处理请求信息
//获取业务层对象
SearchService ss=new SearchServiceImpl();
//调用方法获取提示语数据
List<Data> ld=ss.getSearchInfoService(sdata);
//响应请求信息
//直接响应
resp.getWriter().write(new Gson().toJson(ld));
}
}
3)M层:
SearchService接口
package com.facai.service;
import java.util.List;
import com.facai.pojo.Data;
public interface SearchService {
//根据用户搜索框数据获取提示语数据
List<Data> getSearchInfoService(String sdata);
}
SearchSevice类
package com.facai.service;
import java.util.List;
import com.facai.dao.SearchDao;
import com.facai.dao.impl.SearchDaoImpl;
import com.facai.pojo.Data;
public class SearchServiceImpl implements SearchService {
//创建SearchDao对象
SearchDao sd=new SearchDaoImpl();
@Override
public List<Data> getSearchInfoService(String sdata) {
//根据用户搜索框数据获取提示语数据
return sd.getSearchInfoDao(sdata);
}
}
SearchDao接口
package com.facai.dao;
import java.util.List;
import com.facai.pojo.Data;
public interface SearchDao {
//根据用户搜索框数据获取提示语数据
List<Data> getSearchInfoDao(String sdata);
}
SearchDao类
package com.facai.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import com.facai.dao.SearchDao;
import com.facai.pojo.Data;
import com.facai.util.DBUtil;
public class SearchDaoImpl implements SearchDao{
//根据用户搜索框数据获取提示语数据
@Override
public List<Data> getSearchInfoDao(String sdata) {
//声明jdbc变量
Connection conn=null;
PreparedStatement ps=null;
ResultSet rs=null;
//声明变量
ArrayList<Data> ld=null;
try {
//获取连接
conn=DBUtil.getConnection();
//创建SQL命令
String sql="select * from t_data where title like concat(?,'%') ";
//创建SQL命令对象
ps=conn.prepareStatement(sql);
//给占位符赋值
ps.setString(1, sdata);
//执行查询
rs=ps.executeQuery();
ld=new ArrayList<>();
//遍历
while(rs.next()){
//创建一个Data实体类对象
Data d=new Data();
d.setId(rs.getInt("id"));
d.setTitle(rs.getString("title"));
d.setRemark(rs.getString("remark"));
ld.add(d);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//关闭资源
DBUtil.closeAll(rs, ps, conn);
}
//返回结果
return ld;
}
}
4.问题:现在用户在搜索框上单击键盘的任何一个键都会发起ajax请求,请求提示语数据
解决:判断用户单击的按键符合要求再发起ajax请求
1.获取用户按了哪个键
2.使用event对象进行按键的键盘码值获取
实现:1.鼠标选择提示语
2.键盘上下键选择提示语
3.实现键盘和鼠标的联动操作
4.将显示提示语语的div进行隐藏,当搜索框有文字时再出现
js代码
<!-- 声明js代码域 -->
<script type="text/javascript">
//创建计数器
var count=-1;
//页面加载成功,完成页面资源的初始化
$(function(){
//给搜索框添加键盘弹起事件
$("#search").keyup(function(){
//获取event对象
var eve=window.event;
//获取用户当前点击键盘的键盘码值
var code=eve.keyCode;
//判断code的值是否符合要求
if(code>=65&&code<=90|| code==8){
//获取用户当前搜索框的数据
var sd=$("#search").val();
//判断搜索框数据是否为空
if(sd==""){
return;
}
//发起ajax请求,请求当前用户搜索的提示信息
$.get("search",{sdata:sd},function(data){
//使用eval方法将数据转化为对象
eval("var sd="+data);
//获取提示语div元素对象
var dataDiv=$("#dataDiv");
//清空内容
dataDiv.empty();
//显示隐藏的div
$("#dataDiv").css("display","");
//将提示语数据填充到div中
for(var i=0;i<sd.length;i++){
dataDiv.append("<div style='padding:5px;'>"+sd[i].title+"</div>");
}
//给提示语添加鼠标选择效果
$("#dataDiv div").mouseover(function(){
//清空所有提示语div的背景颜色
$("#dataDiv div").css("background-color","");
//改变当前选择的div背景颜色
$(this).css("background-color","gray");
})
//给提示语添加单击事件,用来选择提示语
$("#dataDiv div").click(function(){
//将当前选择的div提示语放到搜索框中
$("#search").val($(this).html());
//隐藏当前所有填充div提示语
$("#dataDiv div").css("display","none");
//鼠标和键盘进行联动,将当前鼠标选择的div角标赋值给计数器
count=$(this).index();
})
})
}
//判断用户点击的是否是键盘的下键
if(code==40){
//判断是否有提示语
if($("#dataDiv div").length>0){
count=count<$("#dataDiv div").length-1?++count:0;
$("#dataDiv div").css("background-color","");
$("#dataDiv div:eq("+count+")").css("background-color","gray");
//将选择的提示语改变到搜索框中
$("#search").val($("#dataDiv div:eq("+count+")").html());
}
}
//判断用户点击的是否是键盘的上键
if(code==38){
//判断是否有提示语
if($("#dataDiv div").length>0){
count=count>0?--count:$("#dataDiv div").length-1;
$("#dataDiv div").css("background-color","");
$("#dataDiv div:eq("+count+")").css("background-color","gray");
//将选择的提示语改变到搜索框中
$("#search").val($("#dataDiv div:eq("+count+")").html());
}
}
})
})
</script>
在这里设置了只有输入英文才进行ajax请求

5.问题:当用户点击键盘都会触发键盘事件的执行
只要数据符合要求,都会发送ajax请求,请求提示语信息。每点击一次发送一次。
其实只需要最后一次进行请求发送
解决:
延迟发送
JS代码:
在判断搜索框数据是否为空之后
//判断搜索框数据是否为空
if(sd==""){
return;
}
加入
//清除之前要发的请求
window.clearTimeout(id);
//延迟发送请求
window.setTimeout(function(){
//发起ajax请求,请求当前用户搜索的提示信息
$.get("search",{sdata:sd},function(data){
//使用eval方法将数据转化为对象
eval("var sd="+data);
//获取提示语div元素对象
var dataDiv=$("#dataDiv");
//清空内容
dataDiv.empty();
//显示隐藏的div
$("#dataDiv").css("display","");
//将提示语数据填充到div中
for(var i=0;i<sd.length;i++){
dataDiv.append("<div style='padding:5px;'>"+sd[i].title+"</div>");
}
//给提示语添加鼠标选择效果
$("#dataDiv div").mouseover(function(){
//清空所有提示语div的背景颜色
$("#dataDiv div").css("background-color","");
//改变当前选择的div背景颜色
$(this).css("background-color","gray");
})
//给提示语添加单击事件,用来选择提示语
$("#dataDiv div").click(function(){
//将当前选择的div提示语放到搜索框中
$("#search").val($(this).html());
//隐藏当前所有填充div提示语
$("#dataDiv div").css("display","none");
//鼠标和键盘进行联动,将当前鼠标选择的div角标赋值给计数器
count=$(this).index();
})
})
}, 1000);
6.中文搜索
添加正则表达式判断空格
添加判断空格的code值
//声明正则表达式判断空格
var reg=/^\s+$/g;
//获取event对象
var eve=window.event;
//获取用户当前点击键盘的键盘码值
var code=eve.keyCode;
//判断code的值是否符合要求
if(code>=65&&code<=90|| code==8||code==32){
//获取用户当前搜索框的数据
var sd=$("#search").val();
//判断搜索框数据是否为空
if(sd==""||reg.test(sd)){
return;
}
本文介绍了如何使用Ajax、jsp、servlet和jdbc实现搜索框的智能提示功能。功能包括:用户输入关键字时显示下拉提示,支持鼠标和键盘选择提示项。文章详细阐述了功能需求、技术分析、功能实现步骤以及遇到的问题与解决方案,包括键盘事件的处理、延迟发送请求和中文搜索的正则判断。

6069

被折叠的 条评论
为什么被折叠?



