JavaScript实现搜索框的自动完成功能(一)


Posted in Javascript onFebruary 25, 2016

在很多需要搜索的网站, 都会有一个自动完成的搜索框. 方便用户查找他们想要的搜索词. 帮助用户快速找到自己想要的结果. 这种方式是比较友好的. 所以是比较提倡使用的.

先给大家展示下效果图:

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

先看客户端的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事件,这样当我们点击每一项的时候,就可以响应事件。键盘导航的关键是记录当前高亮的索引值,根据索引值来调整背景高亮。显示下拉列表的位置要根据输入框的位置来设置,当浏览器的大小改变时,随时调整下拉列表的位置。

以上所述是小编给大家介绍的JavaScript实现搜索框的自动完成功能(一),希望对大家有所帮助!

Javascript 相关文章推荐
初学JavaScript_03(ExtJs Grid的简单使用)
Oct 02 Javascript
跨域传值即主页面与iframe之间互相传值
Dec 09 Javascript
JavaScript返回网页中超链接数量的方法
Apr 03 Javascript
JavaScript中将数组进行合并的基本方法讲解
Mar 07 Javascript
JavaScript新增样式规则(推荐)
Jul 19 Javascript
使用JQuery选择HTML遍历函数的方法
Sep 17 Javascript
Json对象和字符串互相转换json数据拼接和JSON使用方式详细介绍(小结)
Oct 25 Javascript
详解vuex的简单使用
Mar 12 Javascript
对Vue- 动态元素属性及v-bind和v-model的区别详解
Aug 27 Javascript
微信小程序发送短信验证码完整实例
Jan 07 Javascript
Angular CLI 使用教程指南参考小结
Apr 10 Javascript
uni-app 支持多端第三方地图定位的方法
Jan 03 Javascript
jquery插件之文字间歇自动向上滚动效果代码
Feb 25 #Javascript
jQuery插件ImageDrawer.js实现动态绘制图片动画(附源码下载)
Feb 25 #Javascript
利用jQuery中的ajax分页实现代码
Feb 25 #Javascript
Jquery zTree 树控件异步加载操作
Feb 25 #Javascript
jquery插件jquery.dragscale.js实现拖拽改变元素大小的方法(附demo源码下载)
Feb 25 #Javascript
js判断图片加载完成后获取图片实际宽高的方法
Feb 25 #Javascript
JS面向对象(3)之Object类,静态属性,闭包,私有属性, call和apply的使用,继承的三种实现方法
Feb 25 #Javascript
You might like
PHP 编程的 5个良好习惯
2009/02/20 PHP
PHP中CURL方法curl_setopt()函数的参数分享
2013/01/19 PHP
PHP在线生成二维码代码(google api)
2013/06/03 PHP
iOS+PHP注册登录系统 PHP部分(上)
2016/12/26 PHP
PDO::quote讲解
2019/01/29 PHP
php如何实现数据库的备份和恢复
2020/11/30 PHP
JavaScript 的方法重载效果
2009/08/07 Javascript
用jquery实现下拉菜单效果的代码
2010/07/25 Javascript
HTML5附件拖拽上传drop &amp; google.gears实现代码
2011/04/28 Javascript
浅析onsubmit校验表单时利用ajax的return false无效问题
2013/07/10 Javascript
在Html中使用Requirejs进行模块化开发实例详解
2016/04/15 Javascript
JavaScript中Number对象的toFixed() 方法详解
2016/09/02 Javascript
JS实现title标题栏文字不间断滚动显示效果
2016/09/07 Javascript
Node.js读写文件之批量替换图片的实现方法
2016/09/07 Javascript
把json格式的字符串转换成javascript对象或数组的方法总结
2016/11/03 Javascript
nodejs搭建本地服务器并访问文件的方法
2017/03/03 NodeJs
深入浅析JavaScript中的RegExp对象
2017/09/18 Javascript
JS实现的倒计时恢复按钮点击功能【可用于协议阅读倒计时】
2018/04/19 Javascript
LayUi数据表格自定义赋值方式
2019/10/26 Javascript
如何利用JS将手机号中间四位变成*号
2020/09/29 Javascript
Django中处理出错页面的方法
2015/07/15 Python
Django框架多表查询实例分析
2018/07/04 Python
深入了解Python在HDA中的应用
2019/09/05 Python
Scrapy 配置动态代理IP的实现
2020/09/28 Python
python爬虫实现爬取同一个网站的多页数据的实例讲解
2021/01/18 Python
详解WebSocket跨域问题解决
2018/08/06 HTML / CSS
C#面试题问题集
2016/04/02 面试题
公司员工的自我评价范例
2013/11/01 职场文书
工厂保洁员岗位职责
2013/12/04 职场文书
初中英语教学反思
2014/01/25 职场文书
《寓言两则》教学反思
2014/02/27 职场文书
公益广告宣传方案
2014/02/28 职场文书
广告宣传策划方案
2014/05/21 职场文书
文体活动总结
2015/02/04 职场文书
在js中修改html body的样式
2021/11/11 Javascript
JavaScript最完整的深浅拷贝实现方式详解
2022/02/28 Javascript