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 相关文章推荐
点击下载链接 弹出页面实现代码
Oct 01 Javascript
获取服务器传来的数据 用JS去空格的正则表达式
Mar 26 Javascript
js批量设置样式的三种方法不推荐使用with
Feb 25 Javascript
将list转换为json失败的原因
Dec 17 Javascript
JavaScript实现生成GUID(全局统一标识符)
Sep 05 Javascript
深入学习AngularJS中数据的双向绑定机制
Mar 04 Javascript
Javascript中八种遍历方法的执行速度深度对比
Apr 25 Javascript
浅谈js的解析顺序 作用域 严格模式
Oct 23 Javascript
浅谈angular4.0中路由传递参数、获取参数最nice的写法
Mar 12 Javascript
Bootstrap table 实现树形表格联动选中联动取消功能
Sep 30 Javascript
vue 使用async写数字动态加载效果案例
Jul 18 Javascript
javascript实现时间日期的格式化的方法汇总
Aug 06 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
xml在joomla表单中的应用详解分享
2012/07/19 PHP
php将一维数组转换为每3个连续值组成的二维数组
2016/05/06 PHP
Gird事件机制初级读本
2007/03/10 Javascript
js 模拟实现类似c#下的hashtable的简单功能代码
2010/01/24 Javascript
超简单的jquery的AJAX用法
2010/05/10 Javascript
Javascript insertAfter() 实现函数代码
2011/10/12 Javascript
Javascript 鼠标移动上去小三角形滑块缓慢跟随效果
2013/04/26 Javascript
javascript setTimeout和setInterval计时的区别详解
2013/06/21 Javascript
JS图片切换的具体方法(带缩略图版)
2013/11/12 Javascript
javascript实现按回车键切换焦点
2015/02/09 Javascript
jQuery使用fadein方法实现渐出效果实例
2015/03/27 Javascript
jquery+正则实现统一的表单验证
2015/09/20 Javascript
在网页中插入百度地图的步骤详解
2016/12/02 Javascript
JS去除字符串中空格的方法
2017/02/14 Javascript
原生js实现仿window10系统日历效果的实例
2017/10/31 Javascript
浅谈vue单一组件下动态修改数据时的全部重渲染
2018/03/01 Javascript
解决element-ui中下拉菜单子选项click事件不触发的问题
2018/08/22 Javascript
jQuery实现的导航条点击后高亮显示功能示例
2019/03/04 jQuery
node+vue实现文件上传功能
2020/05/28 Javascript
Tornado服务器中绑定域名、虚拟主机的方法
2014/08/22 Python
python多行字符串拼接使用小括号的方法
2020/03/19 Python
python中的不可变数据类型与可变数据类型详解
2018/09/16 Python
python使用循环打印所有三位数水仙花数的实例
2018/11/13 Python
Python实现的调用C语言函数功能简单实例
2019/03/13 Python
Python魔法方法 容器部方法详解
2020/01/02 Python
Python爬虫分析微博热搜关键词的实现代码
2021/02/22 Python
Nip + Fab官网:英国美容品牌
2019/08/26 全球购物
希腊品牌鞋类销售网站:epapoutsia.gr
2020/03/18 全球购物
Kendra Scott官网:美国领先的时尚配饰品牌
2020/10/22 全球购物
Napapijri西班牙在线商店:夹克、外套、运动衫等
2020/11/05 全球购物
PHP面试题集
2016/12/18 面试题
印刷工程专业应届生求职信
2013/09/29 职场文书
初中生期末评语大全
2014/04/24 职场文书
2014年语文教研组工作总结
2014/12/06 职场文书
一篇文章学会Vue中间件管道
2021/06/20 Vue.js
DE1107机评
2022/04/05 无线电