ajax java 实现自动完成功能


Posted in Javascript onDecember 19, 2012

百度建议给了我们极大的方便,就像我们跟人说话的时候,你点头他知尾,不用多费唇舌,这样我们与之相处久轻松愉悦。

都知道百度建议是用ajax做的,想要做的快速稳定,可复制可移植就不容易了。网上找了半天,好多都是asp或者php的,还有使用jquery的,但说明性文档太少,花时间研究还不如自己来写。根据一个pdf文档提供的资料,用了小半天时间,终于实现了。在此与大家分享。
原理流程图如下:
ajax java 实现自动完成功能 
流程图很明白了,没什么要说的,以下帖代码。
Javascript代码:

var xmlHttpRequest; 
var table; 
var tbody; 
var div; 
var input; 
var curIndex; 
var size; 
var r_userId; 
function createXMLHttpRequest(){ 
if(window.ActiveXObject){ 
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP"); 
}else if(window.XMLHttpRequest){ 
xmlHttpRequest = new XMLHttpRequest(); 
} 
} 
//发送请求 
function findNames(){ 
if(event.keyCode==38||event.keyCode==40){ 
}else{ 
if(input.value.length>0){ 
createXMLHttpRequest(); 
var url = encodeURI(encodeURI("/jforum.html?module=posts&action=findDept&names="+input.value)); 
xmlHttpRequest.open("GET",url,true); 
xmlHttpRequest.onreadystatechange=processMatchResponse; 
xmlHttpRequest.send(null); 
}else{ 
clearNames(); 
} 
} } 
function processMatchResponse(){ 
if(xmlHttpRequest.readyState==4){ 
if(xmlHttpRequest.status==200){ 
//alert(xmlHttpRequest.status); 
//var id = xmlHttpRequest.responseXML.getElementsByTagName("id"); 
var dept = xmlHttpRequest.responseXML.getElementsByTagName("dept"); 
var id = xmlHttpRequest.responseXML.getElementsByTagName("id"); 
setNames(dept,id); 
}else{ 
window.alert("您所请求的页面有异常!"); 
} 
} 
} 
function setNames(depts,ids){ 
clearNames(); 
size = depts.length; 
if(size>0){ 
div.style.visibility = "visible"; 
var row,col1,col2,span; 
for(var i = 0;i < size;i++){ 
row = document.createElement("tr"); 
col1 = document.createElement("td"); 
col1.innerText = depts[i].firstChild.data; 
col2 = document.createElement("td"); 
col2.setAttribute("align","right"); 
col2.setAttribute("id","col2"); 
col2.setAttribute("width","5%"); 
span = document.createElement("span"); 
span.innerText = ids[i].firstChild.data; 
span.style.display = "none"; 
col2.appendChild(span); 

row.appendChild(col1); 
row.appendChild(col2); 
row.onmouseout = function(){ 
this.className = 'mouseOut'; 
} 
row.onmouseover = function(){ 
clearSelected(); 
this.className = 'mouseOver'; 
curIndex = this.rowIndex; 
} 
row.onclick = function(){ 
input.value = this.cells[0].innerText; 
r_userId.value = table.rows[curIndex].cells[1].innerText; 
clearNames(); 
}; 
tbody.appendChild(row); 
} 
row = document.createElement("tr"); 
col2 = document.createElement("td"); 
col1 = document.createElement("td"); 
col2.setAttribute("align","right"); 
link = document.createElement("a"); 
link.href = "javascript:clearNames();"; 
link.innerHTML = "关闭"; 
col1.appendChild(link); 
row.appendChild(col1); 
row.appendChild(col2); 
tbody.appendChild(row); 
} 
} 
function setPosition(){ 
input = document.getElementById("names"); 
r_userId = document.getElementById("r_userId"); 
table = document.getElementById("table"); 
div = document.getElementById("div"); 
tbody = document.getElementById("tbody"); 
div.style.width = input.offsetWidth-2; 
div.style.border = "gray 1px solid"; 
div.style.left = getLeft(input); 
div.style.top = getTop(input)+input.offsetHeight+6; 
curIndex = -1; 
input.focus();//div.style.left+","+div.style.top 
} 
function clearNames(){ 
var ind = tbody.childNodes.length; 
for(i=ind-1;i>=0;i--){ 
tbody.removeChild(tbody.childNodes[i]); 
} 
div.style.visibility="hidden"; 
curIndex = -1; 
} 
function clearSelected(){ 
var ind = tbody.childNodes.length; 
for(var i = ind-1;i>=0;i--){ 
tbody.childNodes[i].className = "mouseOut"; 
} 
} 
function keyDown(){ 
if(div.style.visibility=="visible"){ 
if(event.keyCode ==38){ 
if(curIndex>=0){ 
table.rows[curIndex].className='mouseOut'; 
curIndex = curIndex-1; 
if(curIndex>=0){ 
table.rows[curIndex].className = 'mouseOver'; 
input.value = table.rows[curIndex].cells[0].innerText; 
r_userId.value = table.rows[curIndex].cells[1].innerText; 
} 
} 
} 
if(event.keyCode==40){ 
if(curIndex<size-1){ 
if(curIndex>=0){ 
table.rows[curIndex].className = 'mouseOut'; 
} 
curIndex = curIndex+1; 
table.rows[curIndex].className = 'mouseOver'; 
input.value = table.rows[curIndex].cells[0].innerText; 
r_userId.value = table.rows[curIndex].cells[1].innerText; 
}else{ 
table.rows[curIndex].className = 'mouseOut'; 
curIndex = -1; 
} 
} 
} 
} 
//获取元素的纵坐标 
function getTop(e){ 
var offset=e.offsetTop; 
if(e.offsetParent!=null) offset+=getTop(e.offsetParent); 
return offset; 
} 
//获取元素的横坐标 
function getLeft(e){ 
var offset=e.offsetLeft; 
if(e.offsetParent!=null) offset+=getLeft(e.offsetParent); 
return offset; 
}

代码太多,有点乱,没使用jquery,但更能显示作者的功底。以下分点阐述:
1,setPosition()是用来初始化全局所需要的各个变量,所以在页面加载的时候就要先调用喽,比如在body的onload方法,或者其他方式都可以。
2,findNames()是操作ajax的方法,熟悉ajax的人都可以看明白,里面最主要的是要对参数进行二次编码encodeURI(),相应的在后台要进行解码。
3,processMatchResponse()是回调函数,用来处理从后台返回的数据,这里交给了setNames()来处理。
4,setNames中采用table方式显示提示的内容。这里更多的是JS和node方面的知识。
5,getTop和getLeft方法是获得文本框的绝对位置,相对于浏览器左上角的。
后台java代码如下:
public void findDept() throws IOException{ 
String partDeptName = this.request.getParameter("names"); 
partDeptName = java.net.URLDecoder.decode(partDeptName, "UTF-8"); 
Map<String,String> userMap = DataAccessDriver.getInstance().newUserDAO().getDeptByPart("%" + partDeptName + "%"); this.response.setContentType("text/xml;charset=UTF-8"); 
this.response.setHeader("Cache-Control", "no-cache"); 

ServletOutputStream pw = this.response.getOutputStream(); 
OutputStreamWriter out = new OutputStreamWriter(pw,"UTF-8"); 
out.write("<res>"); 
Iterator<Map.Entry<String, String>> it = userMap.entrySet().iterator(); 
while(it.hasNext()){ 
Map.Entry<String, String> entry=(Map.Entry<String,String>)it.next(); 
out.write("<id>"+entry.getKey()+"</id>"); 
out.write("<dept>"+entry.getValue()+"</dept>"); 
} 
out.write("</res>"); 
out.flush(); 
out.close(); 
}

要点
1,注意对参数进行解码。
2,查询时根据情况进行模糊匹配。
3,返回数据这里采用了xml方式,也可以采用json方式。
4,返回的方式这里采用了
ServletOutputStream pw = this.response.getOutputStream(); 
OutputStreamWriter out = new OutputStreamWriter(pw,"UTF-8");

这样的流是受本系统框架的限制,如果使用单纯的servlet,可以采用PrintWriter out = response.getWriter();当然out的方法是println(),也可以根据自己框架的情况灵活改变。
Javascript 相关文章推荐
jQuery :first选择器使用介绍
Aug 09 Javascript
javascript结合ajax读取txt文件内容
Dec 05 Javascript
javascript实现滑动解锁功能
Dec 31 Javascript
javascript实现随机生成DIV背景色
Jun 20 Javascript
Bootstrap字体图标无法正常显示的解决方法
Oct 08 Javascript
详解vue服务端渲染(SSR)初探
Jun 19 Javascript
JS集合set类的实现与使用方法示例
Feb 01 Javascript
微信小程序如何调用json数据接口并解析
Jun 29 Javascript
深入浅析vue中cross-env的使用
Sep 12 Javascript
如何利用Node.js与JSON搭建简单的动态服务器
Jun 16 Javascript
JavaScript 异步时序问题
Nov 20 Javascript
vue3自定义dialog、modal组件的方法
Jan 04 Vue.js
JavaScript字符串String和Array操作的有趣方法
Dec 18 #Javascript
学习js在线html(富文本,所见即所得)编辑器
Dec 18 #Javascript
javascript jscroll模拟html元素滚动条
Dec 18 #Javascript
Android中资源文件(非代码部分)的使用概览
Dec 18 #Javascript
js获取单选框或复选框值及操作
Dec 18 #Javascript
JQuery触发radio或checkbox的change事件
Dec 18 #Javascript
Jquery为单选框checkbox绑定单击click事件
Dec 18 #Javascript
You might like
SONY SRF-40W电路分析
2021/03/02 无线电
PHP备份/还原MySQL数据库的代码
2011/01/06 PHP
PHP实现全角字符转为半角方法汇总
2015/07/09 PHP
php随机显示指定文件夹下图片的方法
2015/07/13 PHP
PHP面向对象五大原则之接口隔离原则(ISP)详解
2018/04/04 PHP
网上抓的一个特效
2007/05/11 Javascript
超轻量级的基于jquery的三级展开列表
2011/04/26 Javascript
JS实现根据出生年月计算年龄
2014/01/10 Javascript
js中通过父级进行查找定位元素
2014/06/15 Javascript
jQuery使用load()方法载入另外一个网页文件内的指定标签内容到div标签的方法
2015/03/25 Javascript
js实现简单div拖拽功能实例
2015/05/12 Javascript
jQuery实现滚动切换的tab选项卡效果代码
2015/08/26 Javascript
将 vue 生成的 js 上传到七牛的实例
2017/07/28 Javascript
vue中引用阿里字体图标的方法
2018/02/10 Javascript
vue2.0在没有dev-server.js下的本地数据配置方法
2018/02/23 Javascript
JS封装的模仿qq右下角消息弹窗功能示例
2018/08/22 Javascript
Vue动态组件与异步组件实例详解
2019/02/23 Javascript
解决包含在label标签下的checkbox在ie8及以下版本点击事件无效果兼容的问题
2019/10/27 Javascript
js实现选项卡效果
2020/03/07 Javascript
el-table树形表格表单验证(列表生成序号)
2020/05/31 Javascript
Python实现把回车符\r\n转换成\n
2015/04/23 Python
Python编程中flask的简介与简单使用
2018/12/28 Python
Python如何爬取实时变化的WebSocket数据的方法
2019/03/09 Python
Python3实现的旋转矩阵图像算法示例
2019/04/03 Python
python列表推导式操作解析
2019/11/26 Python
在tensorflow中实现屏蔽输出的log信息
2020/02/04 Python
如何基于线程池提升request模块效率
2020/04/18 Python
Python如何实现邮件功能
2020/05/27 Python
详解HTML5 Canvas绘制时指定颜色与透明度的方法
2016/03/25 HTML / CSS
JSF的标签库有哪些
2012/04/27 面试题
学前教育学生自荐信范文
2013/12/31 职场文书
教师求职信
2014/06/17 职场文书
集团财务总监岗位职责
2015/04/03 职场文书
机械原理课程设计心得体会
2016/01/15 职场文书
pytorch加载预训练模型与自己模型不匹配的解决方案
2021/05/13 Python
详解Java实践之适配器模式
2021/06/18 Java/Android