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 相关文章推荐
强悍无比的WEB开发好助手FireBug(Firefox Plugin)
Jan 16 Javascript
Javascript 面向对象特性
Dec 28 Javascript
jquery绑定事件不生效的解决方法
Feb 11 Javascript
jQuery 浮动导航菜单适合购物商品类型的网站
Sep 09 Javascript
EasyUI中datagrid在ie下reload失败解决方案
Mar 09 Javascript
javascript实现多栏闭合展开式广告位菜单效果实例
Aug 05 Javascript
javascript事件模型介绍
May 31 Javascript
基于bootstrap实现bootstrap中文网巨幕效果
May 02 Javascript
Angularjs实现下拉框联动的示例代码
Aug 22 Javascript
Vue-resource拦截器判断token失效跳转的实例
Oct 27 Javascript
JsonProperty 的使用方法详解
Oct 11 Javascript
如何在JavaScript中正确处理变量
Dec 25 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 学习提高路线分享
2011/10/23 PHP
thinkphp3.2.2前后台公用类架构问题分析
2014/11/25 PHP
PHP获取Exif缩略图的方法
2015/07/13 PHP
php+mysql实现简单登录注册修改密码网页
2016/11/30 PHP
Thinkphp事务操作实例(推荐)
2017/04/01 PHP
让firefox支持IE的一些方法的javascript扩展函数代码
2010/01/02 Javascript
20款超赞的jQuery插件 Web开发人员必备
2011/02/26 Javascript
EASYUI TREEGRID异步加载数据实现方法
2012/08/22 Javascript
javascript判断office版本示例
2014/04/11 Javascript
jquery让指定的元素闪烁显示的方法
2015/03/17 Javascript
javascript实现的简单计时器
2015/07/19 Javascript
理解javascript中的原型和原型链
2015/07/30 Javascript
js 实现数值的千分位及保存小数方法(推荐)
2016/08/01 Javascript
web前端开发upload上传头像js示例代码
2016/10/22 Javascript
JS简单添加元素新节点的方法示例
2018/02/10 Javascript
解决vue elementUI 使用el-select 时 change事件的触发问题
2020/11/17 Vue.js
[15:09]DOTA2国际邀请赛采访专栏:Loda
2013/08/06 DOTA
python和C语言混合编程实例
2014/06/04 Python
Python greenlet实现原理和使用示例
2014/09/24 Python
Python求两个文本文件以行为单位的交集、并集与差集的方法
2015/06/17 Python
python简单实现获取当前时间
2016/08/27 Python
你真的了解Python的random模块吗?
2017/12/12 Python
Python代码太长换行的实现
2019/07/05 Python
python执行scp命令拷贝文件及文件夹到远程主机的目录方法
2019/07/08 Python
pygame编写音乐播放器的实现代码示例
2019/11/19 Python
python模式 工厂模式原理及实例详解
2020/02/11 Python
Python 列表中的修改、添加和删除元素的实现
2020/06/11 Python
css背景图片的背景裁切、背景透明度、背景变换等效果运用
2012/12/24 HTML / CSS
html5定位获取当前位置并在百度地图上显示
2014/08/22 HTML / CSS
美国时尚在线:Showpo
2017/09/08 全球购物
伯利陶器:Burleigh Pottery
2018/01/03 全球购物
电气工程及自动化专业自荐书范文
2013/12/18 职场文书
会计专业个人自我鉴定
2014/03/21 职场文书
食品流通安全承诺书
2014/05/22 职场文书
golang 在windows中设置环境变量的操作
2021/04/29 Golang
python实现MD5进行文件去重的示例代码
2021/07/09 Python