基于jquery实现的类似百度搜索的输入框自动完成功能


Posted in Javascript onAugust 23, 2011

废话不多说,直观的看一下:

基于jquery实现的类似百度搜索的输入框自动完成功能

实现这个功能需要服务端配合。客户端通过脚本来展示从服务端取得的数据。

先看客户端的HTML:

 
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
 <head> 
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
 <title>搜索词自动完成</title> 
 <style type="text/css"> 
 #search{ 
 text-align: center; 
position:relative; 
} 
.autocomplete{ 
border: 1px solid #9ACCFB; 
background-color: white; 
text-align: left; 
} 
.autocomplete li{ 
list-style-type: none; 
} 
.clickable { 
cursor: default; 
} 
.highlight { 
background-color: #9ACCFB; 
} 
</style> 
<script type="text/javascript" src="jquery.js"></script> 
<script type="text/javascript"> 
$(function(){ 
//取得div层 
var $search = $('#search'); 
//取得输入框JQuery对象 
var $searchInput = $search.find('#search-text'); 
//关闭浏览器提供给输入框的自动完成 
$searchInput.attr('autocomplete','off'); 
//创建自动完成的下拉列表,用于显示服务器返回的数据,插入在搜索按钮的后面,等显示的时候再调整位置 
var $autocomplete = $('<div class="autocomplete"></div>') 
.hide() 
.insertAfter('#submit'); 
//清空下拉列表的内容并且隐藏下拉列表区 
var clear = function(){ 
$autocomplete.empty().hide(); 
}; 
//注册事件,当输入框失去焦点的时候清空下拉列表并隐藏 
$searchInput.blur(function(){ 
setTimeout(clear,500); 
}); 
//下拉列表中高亮的项目的索引,当显示下拉列表项的时候,移动鼠标或者键盘的上下键就会移动高亮的项目,想百度搜索那样 
var selectedItem = null; 
//timeout的ID 
var timeoutid = null; 
//设置下拉项的高亮背景 
var setSelectedItem = function(item){ 
//更新索引变量 
selectedItem = item ; 
//按上下键是循环显示的,小于0就置成最大的值,大于最大值就置成0 
if(selectedItem < 0){ 
selectedItem = $autocomplete.find('li').length - 1; 
} 
else if(selectedItem > $autocomplete.find('li').length-1 ) { 
selectedItem = 0; 
} 
//首先移除其他列表项的高亮背景,然后再高亮当前索引的背景 
$autocomplete.find('li').removeClass('highlight') 
.eq(selectedItem).addClass('highlight'); 
}; 
var ajax_request = function(){ 
//ajax服务端通信 
$.ajax({ 
'url':'/test/index.jsp', //服务器的地址 
'data':{'search-text':$searchInput.val()}, //参数 
'dataType':'json', //返回数据类型 
'type':'POST', //请求类型 
'success':function(data){ 
if(data.length) { 
//遍历data,添加到自动完成区 
$.each(data, function(index,term) { 
//创建li标签,添加到下拉列表中 
$('<li></li>').text(term).appendTo($autocomplete) 
.addClass('clickable') 
.hover(function(){ 
//下拉列表每一项的事件,鼠标移进去的操作 
$(this).siblings().removeClass('highlight'); 
$(this).addClass('highlight'); 
selectedItem = index; 
},function(){ 
//下拉列表每一项的事件,鼠标离开的操作 
$(this).removeClass('highlight'); 
//当鼠标离开时索引置-1,当作标记 
selectedItem = -1; 
}) 
.click(function(){ 
//鼠标单击下拉列表的这一项的话,就将这一项的值添加到输入框中 
$searchInput.val(term); 
//清空并隐藏下拉列表 
$autocomplete.empty().hide(); 
}); 
});//事件注册完毕 
//设置下拉列表的位置,然后显示下拉列表 
var ypos = $searchInput.position().top; 
var xpos = $searchInput.position().left; 
$autocomplete.css('width',$searchInput.css('width')); 
$autocomplete.css({'position':'relative','left':xpos + "px",'top':ypos +"px"}); 
setSelectedItem(0); 
//显示下拉列表 
$autocomplete.show(); 
} 
} 
}); 
}; 
//对输入框进行事件注册 
$searchInput 
.keyup(function(event) { 
//字母数字,退格,空格 
if(event.keyCode > 40 || event.keyCode == 8 || event.keyCode ==32) { 
//首先删除下拉列表中的信息 
$autocomplete.empty().hide(); 
clearTimeout(timeoutid); 
timeoutid = setTimeout(ajax_request,100); 
} 
else if(event.keyCode == 38){ 
//上 
//selectedItem = -1 代表鼠标离开 
if(selectedItem == -1){ 
setSelectedItem($autocomplete.find('li').length-1); 
} 
else { 
//索引减1 
setSelectedItem(selectedItem - 1); 
} 
event.preventDefault(); 
} 
else if(event.keyCode == 40) { 
//下 
//selectedItem = -1 代表鼠标离开 
if(selectedItem == -1){ 
setSelectedItem(0); 
} 
else { 
//索引加1 
setSelectedItem(selectedItem + 1); 
} 
event.preventDefault(); 
} 
}) 
.keypress(function(event){ 
//enter键 
if(event.keyCode == 13) { 
//列表为空或者鼠标离开导致当前没有索引值 
if($autocomplete.find('li').length == 0 || selectedItem == -1) { 
return; 
} 
$searchInput.val($autocomplete.find('li').eq(selectedItem).text()); 
$autocomplete.empty().hide(); 
event.preventDefault(); 
} 
}) 
.keydown(function(event){ 
//esc键 
if(event.keyCode == 27 ) { 
$autocomplete.empty().hide(); 
event.preventDefault(); 
} 
}); 
//注册窗口大小改变的事件,重新调整下拉列表的位置 
$(window).resize(function() { 
var ypos = $searchInput.position().top; 
var xpos = $searchInput.position().left; 
$autocomplete.css('width',$searchInput.css('width')); 
$autocomplete.css({'position':'relative','left':xpos + "px",'top':ypos +"px"}); 
}); 
}); 
</script> 
</head> 
<body> 
<div id = "search"> 
<label for="search-text">请输入关键词</label><input type="text" id="search-text" name="search-text" /> 
<input type="button" id="submit" value="搜索"/> 
</div> 
</body> 
</html>

服务端的代码,我们这里选择JSP,也可以使用PHP,服务端无所谓,关键是传送数据。
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 
<% 
String []words = {"amani","abc","apple","abstract","an","bike","byebye", 
"beat","be","bing","come","cup","class","calendar","china"}; 
if(request.getParameter("search-text") != null) { 
String key = request.getParameter("search-text"); 
if(key.length() != 0){ 
String json="["; 
for(int i = 0; i < words.length; i++) { 
if(words[i].startsWith(key)){ 
json += "\""+ words[i] + "\"" + ","; 
} 
} 
json = json.substring(0,json.length()-1>0?json.length()-1:1); 
json += "]"; 
System.out.println("json:" + json); 
out.println(json); 
} 
} 
%>

整个过程思路其实挺清晰的,首先在输入框上注册keyup事件,然后在事件中通过ajax获取json对象。取得数据后,每一项数据创建一个li标签,在标签上注册click事件,这样当我们点击每一项的时候,就可以响应事件。键盘导航的关键是记录当前高亮的索引值,根据索引值来调整背景高亮。显示下拉列表的位置要根据输入框的位置来设置,当浏览器的大小改变时,随时调整下拉列表的位置。
JQuery是web前端的利器,有机会的话,大家一定要看一下。
Javascript 相关文章推荐
msn上的tab功能Firefox对childNodes处理的一个BUG
Jan 21 Javascript
Knockoutjs的环境搭建教程
Nov 26 Javascript
基于jQuery实现的美观星级评论打分组件代码
Oct 30 Javascript
使用angularjs创建简单表格
Jan 21 Javascript
ES6中Proxy与Reflect实现重载(overload)的方法
Mar 30 Javascript
Vue.js仿Metronic高级表格(二)数据渲染
Apr 19 Javascript
利用JS对iframe父子(内外)页面进行操作的方法教程
Jun 15 Javascript
vue组件间通信子与父详解(二)
Nov 07 Javascript
为jquery的ajax请求添加超时timeout时间的操作方法
Sep 04 jQuery
node.js Promise对象的使用方法实例分析
Dec 26 Javascript
原生js实现点击轮播切换图片
Feb 11 Javascript
jQuery实现放大镜案例
Oct 19 jQuery
jquery 回车事件实现代码
Aug 23 #Javascript
基于jquery的大众点评,分类导航实现代码
Aug 23 #Javascript
20个非常棒的 jQuery 幻灯片插件和教程分享
Aug 23 #Javascript
基于jquery实现的鼠标拖拽元素复制并写入效果
Aug 23 #Javascript
一些有用的JavaScript和jQuery的片段分享
Aug 23 #Javascript
Fastest way to build an HTML string(拼装html字符串的最快方法)
Aug 20 #Javascript
jQuery最佳实践完整篇
Aug 20 #Javascript
You might like
PHP获取搜索引擎关键字来源的函数(支持百度和谷歌等搜索引擎)
2012/10/03 PHP
destoon会员注册提示“数据校验失败(2)”解决方法
2014/06/21 PHP
PHP时间类完整实例(非常实用)
2015/12/25 PHP
Laravel如何使用Redis共享Session
2018/02/23 PHP
鼠标放在图片上显示大图的JS代码
2013/03/26 Javascript
jQuery实现点击文本框弹出热门标签的提示效果
2013/11/17 Javascript
删除条目时弹出的确认对话框
2014/06/05 Javascript
JavaScript数组常用操作技巧汇总
2014/11/17 Javascript
javascript实现仿腾讯游戏选择
2015/05/14 Javascript
JS实现兼容性好,带缓冲的动感网页右键菜单效果
2015/09/18 Javascript
jquery.validate 自定义验证方法及validate相关参数
2016/01/18 Javascript
JavaScript获取服务器时间的方法详解
2016/12/11 Javascript
基于Vue如何封装分页组件
2016/12/16 Javascript
ECMAScript6变量的解构赋值实例详解
2017/09/19 Javascript
详解node单线程实现高并发原理与node异步I/O
2017/09/21 Javascript
vue中如何创建多个ueditor实例教程
2017/11/14 Javascript
vue.js仿hover效果的实现方法示例
2019/01/28 Javascript
vue自定义指令实现方法详解
2019/02/11 Javascript
laypage+SpringMVC实现后端分页
2019/07/27 Javascript
Vue实现点击按钮复制文本内容的例子
2019/11/09 Javascript
vuex的使用和简易实现
2021/01/07 Vue.js
[46:44]VG vs TNC Supermajor小组赛B组败者组决赛 BO3 第一场 6.2
2018/06/03 DOTA
Python编写百度贴吧的简单爬虫
2015/04/02 Python
python3模块smtplib实现发送邮件功能
2018/05/22 Python
python批量修改图片大小的方法
2018/07/24 Python
详解python中的Turtle函数库
2018/11/19 Python
PyQt5根据控件Id获取控件对象的方法
2019/06/25 Python
有趣的睡衣和礼物:LazyOne
2019/11/27 全球购物
有针对性的求职自荐信
2013/11/14 职场文书
农村婚礼主持词
2014/03/13 职场文书
高等教育专业自荐信范文
2014/03/26 职场文书
2014党委书记四风对照检查材料思想汇报
2014/09/21 职场文书
2014年个人工作总结模板
2014/12/15 职场文书
2015年个人工作总结报告
2015/04/25 职场文书
解决SpringBoot跨域的三种方式
2021/06/26 Java/Android
MySQL系列之十 MySQL事务隔离实现并发控制
2021/07/02 MySQL