jquery 模拟类搜索框自动完成搜索提示功能(改进)


Posted in Javascript onMay 24, 2010

autopoint.js代码:

/* 
* @date: 2010-5-22 21:42:15 
* @author: 胡灵伟 
* Depends: 
* jquery.js 
* 
* function:类似GOOGLE搜索框提示功能 
*/ 
(function($) { 
$.fn.autopoint = function (options) { 
defaults = { 
url:options.url, 
keyLeft : 37,//向左方向键 
keyUp : 38,//向上方向键 
keyRight : 39,//向右方向键 
keyDown : 40,//向下方向键 
keyEnter : 13,//回车键 
listHoverCSS : 'jhover',//提示框列表鼠标悬浮的样式 
tpl : '<div class="list"><div class="word">{word}</div><div class="view">约{view}条记录</div></div>', 
topoffset:options.topoffset||5 
}; 
var options = $.extend(defaults, options); 
var dropDiv = $('<div></div>').addClass('dropDiv').appendTo('body'); 
var isOver = false; 
dropDiv.hover(function(){ 
isOver = true; 
}, function(){ 
isOver = false; 
}); 
return this.each(function(){ 
var pa = $(this); 
$(this).bind('keydown', function(event){ 
if (dropDiv.css('display') != 'none') {//当提示层显示时才对键盘事件处理 
var currentList = dropDiv.find('.' + options.listHoverCSS); 
if (event.keyCode == options.keyDown) {//如果按的是向下方向键 
if (currentList.length == 0) { 
//如果提示列表没有一个被选中,则将列表第一个选中 
$(this).val(getPointWord(dropDiv.find('.list:first') 
.mouseover())); 
} else if (currentList.next().length == 0) { 
//如果是最后一个被选中,则取消选中,即可认为是输入框被选中 
unHoverAll(); 
} else { 
unHoverAll(); 
//将原先选中列的下一列选中 
if (currentList.next().length != 0) 
$(this).val(getPointWord(currentList.next() 
.mouseover())); 
} 
return false; 
} else if (event.keyCode == options.keyUp) {//如果按的是向上方向键 
if (currentList.length == 0) { 
$(this).val(getPointWord(dropDiv.find('.list:last') 
.mouseover())); 
} else if (currentList.prev().length == 0) { 
unHoverAll(); 
} else { 
unHoverAll(); 
if (currentList.prev().length != 0) 
$(this).val(getPointWord(currentList.prev() 
.mouseover())); 
} 
return false; 
}else if(event.keyCode == options.keyEnter) dropDiv.empty().hide(); 
} 
//当按下键之前记录输入框值,以方便查看键弹起时值有没有变 
$(this).attr('alt', $(this).val()); 
}).bind('keyup', function(event){ 
//如果弹起的键是向上或向下方向键则返回 
if(event.keyCode == options.keyDown||event.keyCode == options.keyUp) return; 
if($(this).val() == ''){ 
dropDiv.empty().hide(); 
return; 
} 
//若输入框值没有改变或变为空则返回 
if ($(this).val() == $(this).attr('alt')) 
return; 
getData(pa, $(this).val()); 
}).bind('blur', function(){ 
if(isOver&&dropDiv.find('.' + options.listHoverCSS)!=0) return; 
//文本输入框失去焦点则清空并隐藏提示层 
dropDiv.empty().hide(); 
}); 
/**处理ajax返回成功的方法**/ 
handleResponse = function(parent, json) { 
var isEmpty = true; 
for(var o in json){ 
if(o == 'data') isEmpty = false; 
} 
if(isEmpty) { 
showError("返回数据格式错误,请检查请求URL是否正确!"); 
return; 
} 
if(json['data'].length == 0) { 
//返回数据为空 
return; 
} 
refreshDropDiv(parent, json); 
dropDiv.show(); 
} 
/**处理ajax失败的方法**/ 
handleError = function(error) { 
//showError("由于url错误或超时请求失败!"); 
} 
showError = function(error){ 
alert(error); 
} 
/**通过ajax返回json格式数据生成用来创建dom的字符串**/ 
render = function(parent, json) { 
var res = json['data'] || json; 
var appendStr = ''; 
//用json对象中内容替换模版字符串中匹配/\{([a-z]+)\}/ig的内容,如{word},{view} 
for ( var i = 0; i < res.length; i+=1) { 
appendStr += options.tpl.replace(/\{([a-z]+)\}/ig, function(m, n) { 
return res[i][n]; 
}); 
} 
jebind(parent, appendStr); 
} 
/**将新建dom对象插入到提示框中,并重新绑定mouseover事件监听**/ 
jebind = function(parent, a) { 
dropDiv.append(a); 
dropDiv.find('.list').each(function() { 
$(this).unbind('mouseover').mouseover(function() { 
unHoverAll(); 
$(this).addClass(options.listHoverCSS); 
}).unbind('click').click(function(){ 
parent.val(getPointWord($(this))); 
dropDiv.empty().hide(); 
parent.focus(); 
}); 
}); 
} 
/**将提示框中所有列的hover样式去掉**/ 
unHoverAll = function() { 
dropDiv.find('.list').each(function() { 
$(this).removeClass(options.listHoverCSS); 
}); 
} 
/**在提示框中取得当前选中的提示关键字**/ 
getPointWord = function(p) { 
return p.find('div:first').text() 
} 
/**刷新提示框,并设定样式**/ 
refreshDropDiv = function(parent, json) { 
var left = parent.offset().left; 
var height = parent.height(); 
var top = parent.offset().top + options.topoffset + height; 
var width = options.width || parent.width() + 'px'; 
dropDiv.empty(); 
dropDiv.css( { 
'border' : '1px solid #FE00DF', 
'left' : left, 
'top' : top, 
'width' : width 
}); 
render(parent, json); 
//防止ajax返回之前输入框失去焦点导致提示框不消失 
parent.focus(); 
} 
/**通过ajax向服务器请求数据**/ 
getData = function(parent, word) { 
$.ajax( { 
type : 'GET', 
data : "word="+ word, 
url : options.url, 
dataType : 'json', 
timeout : 1000, 
success : function(json){handleResponse(parent, json);}, 
error : handleError 
}); 
} 
}); 
} 
})(jQuery);

网页上主要样式:
<style type="text/css"> 
.dropDiv { 
position: absolute; 
z-index: 10; 
display: none; 
cursor: hand; 
} 
.dropDiv .jhover { 
background-color: #00FEDF; 
} 
.dropDiv .list { 
float:left; 
width:100%; 
} 
.dropDiv .word { 
float:left; 
} 
.dropDiv .view { 
float:right; 
color: gray; 
text-align: right; 
font-size: 10pt; 
} 
</style>

调用方法:
<script type="text/javascript" src="../js/jquery-1.4.2.min.js"></script> 
<script type="text/javascript" src="../js/autopoint-1.0.1.js"></script> 
<script type="text/javascript"> 
$(function(){ 
$("input").autopoint({url:'http://localhost/xun/ajax.svl?method=getsearchhelp'}); 
}); 
</script> 
<body> 

<input type="text" size="50" /> 

<input type="text" size="50" /> 
</body>

servlet主要部分:
response.setContentType("text/html"); 
response.setHeader("Cache-Control", "no-cache"); 
response.setCharacterEncoding("UTF-8"); 
String word = request.getParameter("word"); 
if(Utils.isBlank(word)) return; 
JSONObject json = new JSONObject(); 
JSONArray array = new JSONArray(); 
Map<String, Object> map1 = new HashMap<String, Object>(); 
map1.put("word", word + "a1"); 
map1.put("view", 10); 
Map<String, Object> map2 = new HashMap<String, Object>(); 
map2.put("word", word + "a2"); 
map2.put("view", 15); 
Map<String, Object> map3 = new HashMap<String, Object>(); 
map3.put("word", word + "a3"); 
map3.put("view", 2); 
array.add(JSONObject.fromObject(map1)); 
array.add(JSONObject.fromObject(map2)); 
array.add(JSONObject.fromObject(map3)); 
json.put("data", array); 
PrintWriter out = response.getWriter(); 
out.print(json.toString()); 
out.close();

其中JSONObject和JSONArray类来自json-lib.jar,为了测试方便,是直接返回数据的,实际应用中可以替换为
从数据源查取数据.
Javascript 相关文章推荐
js 验证密码强弱的小例子
Mar 21 Javascript
js仿百度有啊通栏展示效果实现代码
May 28 Javascript
Javascript Web Slider 焦点图示例源码
Oct 10 Javascript
ajax请求get与post的区别总结
Nov 04 Javascript
js 判断浏览器使用的语言示例代码
Mar 22 Javascript
CascadeView级联组件实现思路详解(分离思想和单链表)
Apr 12 Javascript
vue监听滚动事件实现滚动监听
Apr 11 Javascript
使用JavaScript开发跨平台的桌面应用详解
Jul 27 Javascript
使用JS模拟锚点跳转的实例
Feb 01 Javascript
Element UI框架中巧用树选择器的实现
Dec 12 Javascript
JavaScript的console命令使用实例
Dec 03 Javascript
Vue+element-ui添加自定义右键菜单的方法示例
Dec 08 Vue.js
mysql输出数据赋给js变量报unterminated string literal错误原因
May 22 #Javascript
让mayfish支持mysqli数据库驱动的实现方法
May 22 #Javascript
JavaScript 笔记二 Array和Date对象方法
May 22 #Javascript
Javascript笔记一 js以及json基础使用说明
May 22 #Javascript
javascript Array数组对象的扩展函数代码
May 22 #Javascript
javascript 正则替换 replace(regExp, function)用法
May 22 #Javascript
JQuery 文本框使用小结
May 22 #Javascript
You might like
PHP扩展编写点滴 技巧收集
2010/03/09 PHP
php使用cookie保存登录用户名的方法
2015/01/26 PHP
PHP中cookie知识点学习
2018/05/06 PHP
基于Jquery的文字滚动跑马灯插件(一个页面多个滚动区)
2010/07/26 Javascript
使用GruntJS构建Web程序之安装篇
2014/06/04 Javascript
JavaScript中的Math.SQRT1_2属性使用简介
2015/06/14 Javascript
jQuery检查事件是否触发的方法
2015/06/26 Javascript
基于jquery实现可定制的web在线富文本编辑器附源码下载
2015/11/17 Javascript
jQuery实现可拖拽的许愿墙效果【附demo源码下载】
2016/09/14 Javascript
EasyUI框架 使用Ajax提交注册信息的实现代码
2017/09/27 Javascript
解决vue 路由变化页面数据不刷新的问题
2018/03/13 Javascript
angular项目中bootstrap-datetimepicker时间插件的使用示例
2018/03/15 Javascript
Vue单页应用引用单独的样式文件的两种方式
2018/03/30 Javascript
详解Vue源码之数据的代理访问
2018/12/11 Javascript
Javascript作用域和作用域链原理解析
2020/03/03 Javascript
详解ES6新增字符串扩张方法includes()、startsWith()、endsWith()
2020/05/12 Javascript
python中实现指定时间调用函数示例代码
2017/09/08 Python
Django forms组件的使用教程
2018/10/08 Python
浅谈python3发送post请求参数为空的情况
2018/12/28 Python
Python使用sklearn实现的各种回归算法示例
2019/07/04 Python
Python如何实现强制数据类型转换
2019/11/22 Python
python实现自动化报表功能(Oracle/plsql/Excel/多线程)
2019/12/02 Python
你可能不知道的Python 技巧小结
2020/01/29 Python
Python3读写ini配置文件的示例
2020/11/06 Python
Jupyter Notebook 安装配置与使用详解
2021/01/06 Python
8款精美的CSS3表单设计(登录表单/下拉选择/按钮附演示及源码)
2013/02/04 HTML / CSS
HTML5中的nav标签学习笔记
2016/06/24 HTML / CSS
HTML中使用SVG与SVG预定义形状元素介绍
2013/06/28 HTML / CSS
Burt’s Bees英国官网:世界领先的天然个人护理品牌
2020/08/17 全球购物
运动会广播稿200米(5篇)
2014/10/15 职场文书
小升初自荐信范文
2015/03/05 职场文书
2015年建筑工程工作总结
2015/05/13 职场文书
股东出资协议书
2016/03/21 职场文书
详解非极大值抑制算法之Python实现
2021/06/28 Python
关于python3 opencv 图像二值化的问题(cv2.adaptiveThreshold函数)
2022/04/04 Python
详解Redis的三种常用的缓存读写策略步骤
2022/05/06 Redis