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下弹出窗口的变通
Apr 18 Javascript
js中有关IE版本检测
Jan 04 Javascript
jquery $.ajax相关用法分享
Mar 16 Javascript
jQuery+css+html实现页面遮罩弹出框
Mar 21 Javascript
css transform 3D幻灯片特效实现步骤解读
Mar 27 Javascript
网站404页面3秒后跳到首页的实例代码
Aug 16 Javascript
js实现点击添加一个input节点
Dec 05 Javascript
javascript面向对象程序设计(一)
Jan 29 Javascript
jQuery使用正则表达式替换dom元素标签用法示例
Jan 16 Javascript
weex slider实现滑动底部导航功能
Aug 28 Javascript
JS装饰器函数用法总结
Apr 21 Javascript
微信小程序之几种常见的弹框提示信息实现详解
Jul 11 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单件模式结合命令链模式使用说明
2008/09/07 PHP
PHP使用CURL实现对带有验证码的网站进行模拟登录的方法
2014/07/23 PHP
php求斐波那契数的两种实现方式【递归与递推】
2019/09/09 PHP
php查看一个变量的占用内存的实例代码
2020/03/29 PHP
extjs中grid中嵌入动态combobox的应用
2011/01/01 Javascript
7款吸引人眼球的jQuery/CSS3特效实例分享
2013/04/25 Javascript
JS上传图片前实现图片预览效果的方法
2015/03/02 Javascript
Nodejs实现批量下载妹纸图
2015/05/28 NodeJs
浅析jQuery移动开发中内联按钮和分组按钮的编写
2015/12/04 Javascript
jQuery实现鼠标经过购物车出现下拉框代码(推荐)
2016/07/21 Javascript
Javascript+CSS3实现进度条效果
2016/10/28 Javascript
解决vue-cli中stylus无法使用的问题方法
2017/06/19 Javascript
JavaScript使用Ajax上传文件的示例代码
2017/08/10 Javascript
JS实现非首屏图片延迟加载的示例
2018/01/06 Javascript
javascript数组拍平方法总结
2018/01/20 Javascript
深入理解react-router 路由的实现原理
2018/09/26 Javascript
移动端滑动切换组件封装 vue-swiper-router实例详解
2018/11/25 Javascript
Vue中Table组件Select的勾选和取消勾选事件详解
2019/03/19 Javascript
微信小程序前端promise封装代码实例
2019/08/24 Javascript
让mocha支持ES6模块的方法实现
2020/01/14 Javascript
Vue3 响应式侦听与计算的实现
2020/11/11 Javascript
[09:22]2014DOTA2西雅图国际邀请赛 主赛事第二日TOPPLAY
2014/07/21 DOTA
CentOS7下python3.7.0安装教程
2018/07/30 Python
python使用mitmproxy抓取浏览器请求的方法
2019/07/02 Python
Python使用gluon/mxnet模块实现的mnist手写数字识别功能完整示例
2019/12/18 Python
基于TensorFlow中自定义梯度的2种方式
2020/02/04 Python
基于django 的orm中非主键自增的实现方式
2020/05/18 Python
Django中的DateTimeField和DateField实现
2021/02/24 Python
英国玛莎百货美国官网:Marks & Spencer美国
2018/11/06 全球购物
国际领先的在线时尚服装和配饰店:DressLily
2019/03/03 全球购物
护理专业优质毕业生自荐书
2014/01/31 职场文书
医药销售自荐书
2014/05/29 职场文书
组织鉴定材料
2014/06/02 职场文书
顶岗实习计划书
2015/01/16 职场文书
司机岗位职责
2015/02/04 职场文书
2020年元旦晚会策划书模板
2019/12/30 职场文书