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 相关文章推荐
jquery animate图片模向滑动示例代码
Jan 26 Javascript
正则表达式搭配js轻松处理json文本方便而老古
Feb 17 Javascript
javascript的tab切换原理与效果实现方法
Jan 10 Javascript
WordPress中利用AJAX技术进行评论提交的实现示例
Jan 12 Javascript
AngularJS学习笔记之依赖注入详解
May 16 Javascript
Web打印解决方案之证件套打的实现思路
Aug 29 Javascript
Javascript 链式作用域详细介绍
Feb 23 Javascript
js+html获取系统当前时间
Nov 10 Javascript
Vue.js实现分页查询功能
Nov 15 Javascript
关于单文件组件.vue的使用
Sep 20 Javascript
微信小程序学习笔记之跳转页面、传递参数获得数据操作图文详解
Mar 28 Javascript
JavaScript中this的全面解析及常见实例
May 14 Javascript
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学习之PHP变量
2006/10/09 PHP
php项目打包方法
2008/02/18 PHP
php中使用Akismet防止垃圾评论的代码
2011/06/10 PHP
php数组函数序列之array_push() 数组尾部添加一个或多个元素(入栈),返回新长度。
2011/11/07 PHP
解析PHP SPL标准库的用法(遍历目录,查找固定条件的文件)
2013/06/18 PHP
ThinkPHP模板之变量输出、自定义函数与判断语句用法
2014/11/01 PHP
jquery插件之easing使用
2010/08/19 Javascript
javascript学习笔记(三)显示当时时间的代码
2011/04/08 Javascript
23个超流行的jQuery相册插件整理分享
2011/04/25 Javascript
JS使用for循环遍历Table的所有单元格内容
2014/08/21 Javascript
浏览器检测JS代码(兼容目前各大主流浏览器)
2016/02/21 Javascript
jquery自定义插件——window的实现【示例代码】
2016/05/06 Javascript
JS实现表单多文件上传样式美化支持选中文件后删除相关项
2016/09/30 Javascript
D3.js实现文本的换行详解
2016/10/14 Javascript
利用Ionic2 + angular4实现一个地区选择组件
2017/07/27 Javascript
angularjs路由传值$routeParams详解
2020/09/05 Javascript
vue.js路由mode配置之去掉url上默认的#方法
2019/11/01 Javascript
基于vue hash模式微信分享#号的解决
2020/09/07 Javascript
jquery简易手风琴插件的封装
2020/10/13 jQuery
详解vue-router的导航钩子(导航守卫)
2020/11/02 Javascript
[59:35]DOTA2-DPC中国联赛定级赛 Aster vs DLG BO3第一场 1月8日
2021/03/11 DOTA
Python连接phoenix的方法示例
2017/09/29 Python
python实现简单的单变量线性回归方法
2018/11/08 Python
python实现大文本文件分割
2019/07/22 Python
Python 画出来六维图
2019/07/26 Python
Python3将jpg转为pdf文件的方法示例
2019/12/13 Python
Python 抓取数据存储到Redis中的操作
2020/07/16 Python
Python中对象的比较操作==和is区别详析
2021/02/12 Python
行政主管岗位职责
2013/11/18 职场文书
物理专业大学生职业生涯规划书
2014/02/07 职场文书
暑假安全保证书
2015/02/28 职场文书
端午节寄语2015
2015/03/23 职场文书
埃及王子观后感
2015/06/16 职场文书
广播体操比赛主持词
2015/06/29 职场文书
MySQL的InnoDB存储引擎的数据页结构详解
2022/03/03 MySQL
bose降噪耳机音能消除人声吗
2022/04/19 数码科技