请选择 进入手机版 | 继续访问电脑版
提问

ajax java 实现自动完成功能

  © 程序员  / 倒序浏览
  © 本页面所有内容均为注册会员发布,若有侵权,请发邮件至:weixunnet@vip.qq.com

#楼主# 2019-6-18

跳转到指定楼层
都知道百度建议是用ajax做的,想要做的快速稳定,可复制可移植就不容易了,花时间研究还不如自己来写。根据一个pdf文档提供的资料,用了小半天时间,终于实现了。在此与大家分享
百度建议给了我们极大的方便,就像我们跟人说话的时候,你点头他知尾,不用多费唇舌,这样我们与之相处久轻松愉悦。

都知道百度建议是用ajax做的,想要做的快速稳定,可复制可移植就不容易了。网上找了半天,好多都是asp或者php的,还有使用jquery的,但说明性文档太少,花时间研究还不如自己来写。根据一个pdf文档提供的资料,用了小半天时间,终于实现了。在此与大家分享。
原理流程图如下:
[img=360,510 src=][/img]

流程图很明白了,没什么要说的,以下帖代码。
Javascript代码:
  1. var xmlHttpRequest;
  2. var table;
  3. var tbody;
  4. var div;
  5. var input;
  6. var curIndex;
  7. var size;
  8. var r_userId;
  9. function createXMLHttpRequest(){
  10. if(window.ActiveXObject){
  11. xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
  12. }else if(window.XMLHttpRequest){
  13. xmlHttpRequest = new XMLHttpRequest();
  14. }
  15. }
  16. //发送请求
  17. function findNames(){
  18. if(event.keyCode==38||event.keyCode==40){
  19. }else{
  20. if(input.value.length>0){
  21. createXMLHttpRequest();
  22. var url = encodeURI(encodeURI("/jforum.html?module=posts&action=findDept&names="+input.value));
  23. xmlHttpRequest.open("GET",url,true);
  24. xmlHttpRequest.onreadystatechange=processMatchResponse;
  25. xmlHttpRequest.send(null);
  26. }else{
  27. clearNames();
  28. }
  29. }
  30. }
  31. function processMatchResponse(){
  32. if(xmlHttpRequest.readyState==4){
  33. if(xmlHttpRequest.status==200){
  34. //alert(xmlHttpRequest.status);
  35. //var id = xmlHttpRequest.responseXML.getElementsByTagName("id");
  36. var dept = xmlHttpRequest.responseXML.getElementsByTagName("dept");
  37. var id = xmlHttpRequest.responseXML.getElementsByTagName("id");
  38. setNames(dept,id);
  39. }else{
  40. window.alert("您所请求的页面有异常!");
  41. }
  42. }
  43. }
  44. function setNames(depts,ids){
  45. clearNames();
  46. size = depts.length;
  47. if(size>0){
  48. div.style.visibility = "visible";
  49. var row,col1,col2,span;
  50. for(var i = 0;i < size;i++){
  51. row = document.createElement("tr");
  52. col1 = document.createElement("td");
  53. col1.innerText = depts[i].firstChild.data;
  54. col2 = document.createElement("td");
  55. col2.setAttribute("align","right");
  56. col2.setAttribute("id","col2");
  57. col2.setAttribute("width","5%");
  58. span = document.createElement("span");
  59. span.innerText = ids[i].firstChild.data;
  60. span.style.display = "none";
  61. col2.appendChild(span);
  62. row.appendChild(col1);
  63. row.appendChild(col2);
  64. row.onmouseout = function(){
  65. this.className = 'mouseOut';
  66. }
  67. row.onmouseover = function(){
  68. clearSelected();
  69. this.className = 'mouseOver';
  70. curIndex = this.rowIndex;
  71. }
  72. row.onclick = function(){
  73. input.value = this.cells[0].innerText;
  74. r_userId.value = table.rows[curIndex].cells[1].innerText;
  75. clearNames();
  76. };
  77. tbody.appendChild(row);
  78. }
  79. row = document.createElement("tr");
  80. col2 = document.createElement("td");
  81. col1 = document.createElement("td");
  82. col2.setAttribute("align","right");
  83. link = document.createElement("a");
  84. link.href = "javascript:clearNames();";
  85. link.innerHTML = "关闭";
  86. col1.appendChild(link);
  87. row.appendChild(col1);
  88. row.appendChild(col2);
  89. tbody.appendChild(row);
  90. }
  91. }
  92. function setPosition(){
  93. input = document.getElementById("names");
  94. r_userId = document.getElementById("r_userId");
  95. table = document.getElementById("table");
  96. div = document.getElementById("div");
  97. tbody = document.getElementById("tbody");
  98. div.style.width = input.offsetWidth-2;
  99. div.style.border = "gray 1px solid";
  100. div.style.left = getLeft(input);
  101. div.style.top = getTop(input)+input.offsetHeight+6;
  102. curIndex = -1;
  103. input.focus();//div.style.left+","+div.style.top
  104. }
  105. function clearNames(){
  106. var ind = tbody.childNodes.length;
  107. for(i=ind-1;i>=0;i--){
  108. tbody.removeChild(tbody.childNodes[i]);
  109. }
  110. div.style.visibility="hidden";
  111. curIndex = -1;
  112. }
  113. function clearSelected(){
  114. var ind = tbody.childNodes.length;
  115. for(var i = ind-1;i>=0;i--){
  116. tbody.childNodes[i].className = "mouseOut";
  117. }
  118. }
  119. function keyDown(){
  120. if(div.style.visibility=="visible"){
  121. if(event.keyCode ==38){
  122. if(curIndex>=0){
  123. table.rows[curIndex].className='mouseOut';
  124. curIndex = curIndex-1;
  125. if(curIndex>=0){
  126. table.rows[curIndex].className = 'mouseOver';
  127. input.value = table.rows[curIndex].cells[0].innerText;
  128. r_userId.value = table.rows[curIndex].cells[1].innerText;
  129. }
  130. }
  131. }
  132. if(event.keyCode==40){
  133. if(curIndex<size-1){
  134. if(curIndex>=0){
  135. table.rows[curIndex].className = 'mouseOut';
  136. }
  137. curIndex = curIndex+1;
  138. table.rows[curIndex].className = 'mouseOver';
  139. input.value = table.rows[curIndex].cells[0].innerText;
  140. r_userId.value = table.rows[curIndex].cells[1].innerText;
  141. }else{
  142. table.rows[curIndex].className = 'mouseOut';
  143. curIndex = -1;
  144. }
  145. }
  146. }
  147. }
  148. //获取元素的纵坐标
  149. function getTop(e){
  150. var offset=e.offsetTop;
  151. if(e.offsetParent!=null) offset+=getTop(e.offsetParent);
  152. return offset;
  153. }
  154. //获取元素的横坐标
  155. function getLeft(e){
  156. var offset=e.offsetLeft;
  157. if(e.offsetParent!=null) offset+=getLeft(e.offsetParent);
  158. return offset;
  159. }
复制代码
代码太多,有点乱,没使用jquery,但更能显示作者的功底。以下分点阐述:
1,setPosition()是用来初始化全局所需要的各个变量,所以在页面加载的时候就要先调用喽,比如在body的onload方法,或者其他方式都可以。
2,findNames()是操作ajax的方法,熟悉ajax的人都可以看明白,里面最主要的是要对参数进行二次编码encodeURI(),相应的在后台要进行解码。
3,processMatchResponse()是回调函数,用来处理从后台返回的数据,这里交给了setNames()来处理。
4,setNames中采用table方式显示提示的内容。这里更多的是JS和node方面的知识。
5,getTop和getLeft方法是获得文本框的绝对位置,相对于浏览器左上角的。
后台java代码如下:
  1. public void findDept() throws IOException{
  2. String partDeptName = this.request.getParameter("names");
  3. partDeptName = java.net.URLDecoder.decode(partDeptName, "UTF-8");
  4. Map<String,String> userMap = DataAccessDriver.getInstance().newUserDAO().getDeptByPart("%" + partDeptName + "%");
  5. this.response.setContentType("text/xml;charset=UTF-8");
  6. this.response.setHeader("Cache-Control", "no-cache");
  7. ServletOutputStream pw = this.response.getOutputStream();
  8. OutputStreamWriter out = new OutputStreamWriter(pw,"UTF-8");
  9. out.write("<res>");
  10. Iterator<Map.Entry<String, String>> it = userMap.entrySet().iterator();
  11. while(it.hasNext()){
  12. Map.Entry<String, String> entry=(Map.Entry<String,String>)it.next();
  13. out.write("<id>"+entry.getKey()+"</id>");
  14. out.write("<dept>"+entry.getValue()+"</dept>");
  15. }
  16. out.write("</res>");
  17. out.flush();
  18. out.close();
  19. }
复制代码
要点
1,注意对参数进行解码。
2,查询时根据情况进行模糊匹配。
3,返回数据这里采用了xml方式,也可以采用json方式。
4,返回的方式这里采用了
  1. ServletOutputStream pw = this.response.getOutputStream();
  2. OutputStreamWriter out = new OutputStreamWriter(pw,"UTF-8");
复制代码
这样的流是受本系统框架的限制,如果使用单纯的servlet,可以采用PrintWriter out = response.getWriter();当然out的方法是println(),也可以根据自己框架的情况灵活改变。
回复

使用道具

成为第一个回答人

B Color Link Quote Code Smilies
Archiver|手机版|小黑屋|翁笔
翁笔联系邮箱:weixunnet@vip.qq.com 本站服务器由二联网赞助提供