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 相关文章推荐
js文件中调用js的实现方法小结
Oct 23 Javascript
jQuery 回车事件enter使用示例
Feb 18 Javascript
使用jquery选择器如何获取父级元素、同级元素、子元素
May 14 Javascript
jquery实现表单验证简单实例演示
Nov 23 Javascript
Bootstrap carousel轮转图的使用实例详解
May 17 Javascript
canvas知识总结
Jan 25 Javascript
Vue组件模板形式实现对象数组数据循环为树形结构(实例代码)
Jul 31 Javascript
JavaScrip数组删除特定元素的几种方法总结
Sep 06 Javascript
vue-router实现组件间的跳转(参数传递)
Nov 07 Javascript
微信小程序动态生成二维码的实现代码
Jul 25 Javascript
js实现导航跟随效果
Nov 17 Javascript
利用Vconsole和Fillder进行移动端抓包调试方法
Mar 05 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
最贵的咖啡是怎么产生的,它的风味怎么样?
2021/03/04 新手入门
php中文件上传的安全问题
2006/10/09 PHP
浅谈PHP中单引号和双引号到底有啥区别呢?
2015/03/04 PHP
关于php中的json_encode()和json_decode()函数的一些说明
2016/11/20 PHP
PHP+Ajax简单get验证操作示例
2019/03/02 PHP
PHP7引入的&quot;??&quot;和&quot;?:&quot;的区别讲解
2019/04/08 PHP
HTML node相关的一些资料整理
2010/01/01 Javascript
javascrpt绑定事件之匿名函数无法解除绑定问题
2012/12/06 Javascript
基于JavaScript实现通用tab选项卡(通用性强)
2016/01/07 Javascript
jQuery中$.each()函数的用法引申实例
2016/05/12 Javascript
基于jQuery下拉选择框插件支持单选多选功能代码
2016/06/07 Javascript
工作中比较实用的JavaScript验证和数据处理的干货(经典)
2016/08/03 Javascript
浅谈js对象的创建和对6种继承模式的理解和遐想
2016/10/16 Javascript
jQuery监听浏览器窗口大小的变化实例
2017/02/07 Javascript
多个上传文件用js验证文件的格式和大小的方法(推荐)
2017/03/09 Javascript
JavaScript基础进阶之数组方法总结(推荐)
2017/09/04 Javascript
setTimeout时间设置为0详细解析
2018/03/13 Javascript
AngularJS日期格式化常见操作实例分析
2018/05/17 Javascript
Vue页面手动刷新,实现导航栏激活项还原到初始状态
2020/08/06 Javascript
Python实现从订阅源下载图片的方法
2015/03/11 Python
Python中的ctime()方法使用教程
2015/05/22 Python
如何使用七牛Python SDK写一个同步脚本及使用教程
2015/08/23 Python
使用Python的Flask框架表单插件Flask-WTF实现Web登录验证
2016/07/12 Python
Python排序算法之选择排序定义与用法示例
2018/04/29 Python
django admin后台添加导出excel功能示例代码
2019/05/15 Python
python将三维数组展开成二维数组的实现
2019/11/30 Python
SEPHORA丝芙兰捷克官网:购买香水、化妆品和护肤品
2018/11/26 全球购物
CK加拿大官网:Calvin Klein加拿大
2020/03/14 全球购物
美国一站式电动和手动工具商店:International Tool
2020/11/26 全球购物
软件配置管理有什么好处
2015/04/15 面试题
竞聘演讲稿范文
2014/01/12 职场文书
民主生活会发言材料
2014/10/20 职场文书
家长对学校的意见和建议
2015/06/03 职场文书
sql中mod()函数取余数的用法
2021/05/29 SQL Server
CSS3实现360度循环旋转功能
2022/02/12 HTML / CSS
Vue的过滤器你真了解吗
2022/02/24 Vue.js