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 相关文章推荐
Nginx上传文件全部缓存解决方案
Aug 17 Javascript
Angularjs中如何使用filterFilter函数过滤
Feb 06 Javascript
基于JS实现移动端访问PC端页面时跳转到对应的移动端网页
Dec 24 Javascript
JavaScript 深层克隆对象详解及实例
Nov 03 Javascript
概述jQuery中的ajax方法
Dec 16 Javascript
移动端点击态处理的三种实现方式
Jan 12 Javascript
js操作浏览器的参数方法
Jan 21 Javascript
jquery实现图片跟随鼠标的实例
Oct 17 jQuery
node的process以及child_process模块学习笔记
Mar 06 Javascript
AngularJS中的作用域实例分析
May 16 Javascript
VSCode搭建React Native环境
May 07 Javascript
基于JavaScript实现简单抽奖功能代码实例
Oct 20 Javascript
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
php通过array_unshift函数添加多个变量到数组前端的方法
2015/03/18 PHP
PHP设计模式之装饰者模式代码实例
2015/05/11 PHP
PHP中利用sleep函数实现定时执行功能实现代码
2016/08/25 PHP
Yii 2.0在Grid中格式化时间方法示例
2017/06/06 PHP
PHP折半(二分)查找算法实例分析
2018/05/12 PHP
Centos7.7 64位利用本地完整安装包安装lnmp/lamp套件教程
2021/03/09 Servers
飞鱼(shqlsl) javascript作品集
2006/12/16 Javascript
利用javascript中的call实现继承
2007/01/22 Javascript
JavaScript中的Window窗口对象
2008/01/16 Javascript
JS getStyle获取最终样式函数代码
2010/04/01 Javascript
常见效果实现之返回顶部(结合淡入、淡出、减速滚动)
2012/01/04 Javascript
解决Extjs上传图片无法预览的解决方法
2012/03/22 Javascript
jquery中通过父级查找进行定位示例
2013/06/28 Javascript
jQuery插件slides实现无缝轮播图特效
2015/04/17 Javascript
Nodejs如何搭建Web服务器
2016/03/28 NodeJs
javascript实现延时显示提示框特效代码
2016/04/27 Javascript
浅谈Web页面向后台提交数据的方式和选择
2016/09/23 Javascript
AngularJS表单验证中级篇(3)
2016/09/28 Javascript
js的三种继承方式详解
2017/01/21 Javascript
浅谈regExp的test方法取得的值变化的原因及处理方法
2017/03/01 Javascript
vue 实现左右拖拽元素并且不超过他的父元素的宽度
2018/11/30 Javascript
手把手带你封装一个vue component第三方库
2019/02/14 Javascript
javascript的惯性运动实现代码实例
2019/09/07 Javascript
Vue实现boradcast和dispatch的示例
2020/11/13 Javascript
python让图片按照exif信息里的创建时间进行排序的方法
2015/03/16 Python
Python实现文件按照日期命名的方法
2015/07/09 Python
在IPython中执行Python程序文件的示例
2018/11/01 Python
简单掌握CSS3将文字描边及填充文字颜色的方法
2016/03/07 HTML / CSS
Application Cache未缓存文件无法访问无法加载问题
2014/05/31 HTML / CSS
家得宝墨西哥官网:The Home Depot墨西哥
2019/11/18 全球购物
霸气押韵的班级口号
2014/06/09 职场文书
学校班班通实施方案
2014/06/11 职场文书
学习保证书怎么写
2015/02/26 职场文书
行政答辩状范文
2015/05/21 职场文书
Python使用scapy模块发包收包
2021/05/07 Python
使用 Apache Superset 可视化 ClickHouse 数据的两种方法
2021/07/07 Servers