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 相关文章推荐
javascript实现的listview效果
Apr 28 Javascript
Javascript 各浏览器的 Javascript 效率对比
Jan 23 Javascript
javascript:以前写的xmlhttp池,代码
May 18 Javascript
用JavaScript将从数据库中读取出来的日期型格式化为想要的类型。
Aug 15 Javascript
JQuery 图片延迟加载并等比缩放插件
Nov 09 Javascript
在iframe里的页面编写js,实现在父窗口上创建动画效果展开和收缩的div(不变动iframe父窗口代码)
Dec 20 Javascript
jQuery满屏焦点图左右滚动特效代码分享
Sep 07 Javascript
.net MVC+Bootstrap下使用localResizeIMG上传图片
Apr 21 Javascript
vue两个组件间值的传递或修改方式
Jul 04 Javascript
使用vue2.0创建的项目的步骤方法
Sep 25 Javascript
Layui 带多选框表格监听事件以及按钮自动点击写法实例
Sep 02 Javascript
js实现特别简单的钟表效果
Sep 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
spl_autoload_register与autoload的区别详解
2013/06/03 PHP
深入file_get_contents函数抓取内容失败的原因分析
2013/06/25 PHP
jQuery ui1.7 dialog只能弹出一次问题
2009/08/27 Javascript
ANGULARJS中使用JQUERY分页控件
2015/09/16 Javascript
Javascript闭包实例详解
2015/11/29 Javascript
js删除Array数组中指定元素的两种方法
2016/08/03 Javascript
angularjs 源码解析之injector
2016/08/22 Javascript
Bootstrap3 datetimepicker控件使用实例
2016/12/13 Javascript
js实现获取鼠标当前的位置
2016/12/14 Javascript
jQuery Easyui 下拉树组件combotree
2016/12/16 Javascript
Angular中使用$watch监听object属性值的变化(详解)
2017/04/24 Javascript
vue高德地图之玩转周边
2017/06/16 Javascript
Vue+Vux项目实践完整代码
2017/11/30 Javascript
浅谈Vue 数据响应式原理
2018/05/07 Javascript
JavaScript实现的DOM绘制柱状图效果示例
2018/08/08 Javascript
基于layui内置模块(element常用元素的操作)
2019/09/20 Javascript
JavaScript图片旋转效果实现方法详解
2020/06/28 Javascript
JavaScript实现下拉列表
2021/01/20 Javascript
Python实现二分查找算法实例
2015/05/26 Python
python 字符串和整数的转换方法
2018/06/25 Python
python: 判断tuple、list、dict是否为空的方法
2018/10/22 Python
Python 把序列转换为元组的函数tuple方法
2019/06/27 Python
Python爬虫学习之翻译小程序
2019/07/30 Python
使用python创建Excel工作簿及工作表过程图解
2020/05/27 Python
python利用文件时间批量重命名照片和视频
2021/02/09 Python
如何用 Python 制作一个迷宫游戏
2021/02/25 Python
英国剑桥包官网:The Cambridge Satchel Company
2016/08/01 全球购物
水电工岗位职责
2014/02/12 职场文书
优秀护士获奖感言
2014/02/20 职场文书
环保公益广告语
2014/03/13 职场文书
电子信息工程自荐信
2014/05/26 职场文书
集体生日活动方案
2014/08/18 职场文书
毕业生对母校寄语
2015/02/26 职场文书
班组长如何制订适合本班组的工作计划?
2019/07/10 职场文书
python实现socket简单通信的示例代码
2021/04/13 Python
浅谈Python 中的复数问题
2021/05/19 Python