jquery实现搜索框类似提示功
用JQuery实现的类似GOOGLE\BAIDU搜索框的提示功能.
autopoint.js代码:
/* * @author: 范永强 * Depends: * jquery.js * * function:类似GOOGLE搜索框提示功能 * use:$("#input1, #input2").autopoint({url:"url", submit:["submit1", "submit2"]}); * 对所有需要自动提示功能的输入框对象使用autopoint方法, * url为ajax提交的url,submit为输入框enter键提交的action */ (function($) { $.fn.autopoint = function (options) { var bt = $.browser; //根据浏览器设定不同属性 dialect = bt.msie?{ topoffset:5,//提示框top属性与输入框偏移 widthoffset:6//提示框width属性与输入框偏移 }:bt.mozilla?{ topoffset:5, widthoffset:2 }:bt.safari?{ topoffset:6, widthoffset:2 }:bt.opera?{ topoffset:5, widthoffset:2 }:{ topoffset:5, widthoffset:2 }; defaults = { url:options.url, keyUp : 38,//向上方向键 keyDown : 40,//向下方向键 keyEnter : 13,//回车键 listHoverCSS : 'jhover',//提示框列表鼠标悬浮的样式 tpl : '<div class="list"><div class="word">{word}</div><div class="view">{view}</div></div>', submit:options.submit }; var originalVal = new Array(); var lastVal = new Array(); var options = $.extend(defaults, $.extend(dialect, options)); var dropDiv = $('<div></div>').addClass('dropDiv').appendTo('body'); return this.each(function(i){ 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) { originalVal[i] = $(this).val(); //如果提示列表没有一个被选中,则将列表第一个选中 $(this).val(getPointWord(dropDiv.find('.list:first') .mouseover())); } else if (currentList.next().length == 0) { //如果是最后一个被选中,则取消选中,即可认为是输入框被选中 unHoverAll(); $(this).val(originalVal[i]); } 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) { originalVal[i] = $(this).val(); $(this).val(getPointWord(dropDiv.find('.list:last') .mouseover())); } else if (currentList.prev().length == 0) { unHoverAll(); $(this).val(originalVal[i]); } else { unHoverAll(); if (currentList.prev().length != 0) $(this).val(getPointWord(currentList.prev() .mouseover())); } return false; }else if(event.keyCode == options.keyEnter) { //console.debug(currentList.length); if(currentList.length == 0) if(options.submit[i]) { $('#'+options.submit[i]).submit(); } dropDiv.empty().hide(); return; } }else if(event.keyCode == options.keyEnter) //console.debug(options.submit[i]); if(options.submit[i]) { $('#'+options.submit[i]).submit(); return; } }).bind('keyup', function(event){ //输入框值没有改变返回 if ($(this).val() == lastVal[i]) return; //当按键弹起记录输入框值,以方便查看键值有没有变 lastVal[i] = $(this).val(); //输入框值变为空返回 if($(this).val() == ''){ dropDiv.empty().hide(); return; } //如果按下的向上或是向下键,说明在选择 if(event.keyCode == options.keyUp||event.keyCode == options.keyDown) return; //输入框中值有变化,发送请求 getData(pa, $(this).val()); }).bind('blur', function(){ //输入框失去焦点隐藏提示框,mousedown比 //blur优先触发所以先处理选择提示框的内容 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是否正确!"); dropDiv.empty().hide(); return; } if(json['data'].length == 0) { //返回数据为空 dropDiv.empty().hide(); return; } refreshDropDiv(parent, json); dropDiv.show(); }; /**处理ajax失败的方法**/ handleError = function(error) { dropDiv.empty().hide(); showError("请求失败!"+arguments[1]); }; 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('mousedown').mousedown(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()+options.widthoffset) + 'px'; dropDiv.empty(); dropDiv.css( { //'border' : '1px solid #999', 'left' : left, 'top' : top, 'width' : width }); render(parent, json); //防止ajax返回之前输入框失去焦点导致提示框不消失 parent.focus(); }; /**通过ajax向服务器请求数据**/ getData = function(parent, word) { $.ajax( { type : 'POST', data : {word:word,rand:Math.random()}, 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; border:1px solid #7F9DB9; } .dropDiv .jhover { background-color: #D5E2FF; } .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.js"></script> <script type="text/javascript"> $(function(){ $("input").autopoint({url:'http://localhost/xun/ajax.svl?method=getsearchhelp',submit:["action1", "action2"]}); }); </script> </head> <body> <input type="text" id="search" name="search" size="50" autocomplete="off"> <br /> <br /> <br /> <br /> <br /> <input type="text" size="50" autocomplete="off" /> </body>
servlet主要部分:
1 response.setContentType("text/html"); 2 response.setHeader("Cache-Control", "no-cache"); 3 response.setCharacterEncoding("UTF-8"); 4 String word = request.getParameter("word"); 5 if(Utils.isBlank(word)) return; 6 JSONObject json = new JSONObject(); 7 JSONArray array = new JSONArray(); 8 Map<String, Object> map1 = new HashMap<String, Object>(); 9 map1.put("word", word + "a1"); 10 map1.put("view", 10); 11 Map<String, Object> map2 = new HashMap<String, Object>(); 12 map2.put("word", word + "a2"); 13 map2.put("view", 15); 14 Map<String, Object> map3 = new HashMap<String, Object>(); 15 map3.put("word", word + "a3"); 16 map3.put("view", 2); 17 array.add(JSONObject.fromObject(map1)); 18 array.add(JSONObject.fromObject(map2)); 19 array.add(JSONObject.fromObject(map3)); 20 json.put("data", array); 21 PrintWriter out = response.getWriter(); 22 out.print(json.toString()); 23 out.close();
其中JSONObject和JSONArray类来自json-lib.jar,为了测试方便,是直接返回数据的,实际应用中可以替换为
从数据源查取数据.