一个纯手工的模仿BAIDU和GOOGLE的输入信息自动匹配的功能封装,为了应付项目组的需要。本人基本上是不太会写JS,高人看了代码千万不要笑哦。但思路上对新手还是有些帮助的,我想是这样的。好了,废话不多说,看代码...
JSP代码(autoAdaptation.jsp):页面效果可以通过访问此页来观察
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%-- 加载所需的JS控件等(这个common_tree当中还封装了一个EXTJS的树) --%>
<%@include file="/pages/commons/common_tree.jsp" %>
<%--
要使用自动匹配的输入框
其中的style属性很重要,在adaption方法中会使用到其中的值。
--%>
输入1,a,b时均会看到自动匹配效果:
<%--
在IE6中DIV的显示级别没有SELECT高,
直接加底色是挡不住这个SELECT控件的,
处理方法很简单,先用IFRAME遮住SELECT
再用DIV遮住IFRAME就行了。
--%>
校验自动匹配组件是否能够遮挡此控件:
-----------------------------------------
主页中引入的JSP内容(<%@include file="/pages/commons/common_tree.jsp" %>),此部分引入了EXTJS的包,没有减肥,但此功能只用到了一个EXT的AJAX功能,使用DWR或者JQUERY也可以实现相同的效果,如果你觉得EXT太肥了,可以改掉。
<%String basePath = request.getContextPath(); %>
<%-- EXTJS start--%>
-----------------------------------------
CSS (/js_component/commons/css/autoAdaptation.css):没有什么美观效果,完全是为了实现功能,牛人可以通过CSS来调整显示效果,我基本上不会用CSS。
ul.list {
list-style: none;
margin:0px;
}
ul.list li {
margin:0;
padding:0;
line-height:1.2em;
font-size:9pt;
}
.adaptionIFrame {
display: none;background-color:#FFFFFF; z-index:1; border:1px #0066FF solid;
}
.adaptionDiv {
display: none;background-color:#FFFFFF; z-index:1; border:1px #0066FF solid;
}
.adaptionDiv_body {
}
-----------------------------------------
JS(/js_component/commons/autoAdaptation.js):这是实现自动匹配的核心逻辑,写的比较丑陋,还没来得及优化。
function adaption(input){//主方法
new AutoAdaption().adaption(input);
}
document.οnclick=mouseClick;//监听鼠标点击的控件
var mouseClickElId = '';
function mouseClick(evt){
if(evt){//不是ie
mouseClickElId = (evt.target.id);
}else if(window.event){//ie
mouseClickElId = (window.event.srcElement.id);
}
if(!(mouseClickElId.length>'adaptionDiv'.length-1)){//如果鼠标点击了指定范围以外时
new AutoAdaption().adaptionOver();//关闭自动匹配的提示窗口
}
}
AutoAdaption = function (){
this.adaption = function(input){
var para = input.value;
var requestConfig = {
url:getRootPath()+'/pages/autoadaptation/autoAdaptation_data.jsp',
params:{info:input.value},
callback:function(options,success,response){
var res = response.responseText;
var resArray = res.split(";");
if(res.length>2){
var adaptionDiv_body = setFrame(input);
var sUl = "";
"
var li = "";
for(var i=0;i
var ss = " οnmοusemοve='new AutoAdaption().onmousemoveLi(this)' οnmοuseοut='new AutoAdaption().onmouseoutLi(this)' style='background-color: #FFFFFF'";
li+="
}
var eUl = "
adaptionDiv_body.innerHTML=sUl+li+eUl;
}else{
new AutoAdaption().adaptionOver();
}
}
}
Ext.Ajax.request(requestConfig);
}
this.adaptionLi = function(li,id){
getEl(id).value = li.innerText;
new AutoAdaption().adaptionOver();
}
this.adaptionOver = function(){
var adaptionIFrame = getEl("adaptionIFrame");
adaptionIFrame.style.display = 'none';
var adaptionDiv = getEl("adaptionDiv");
adaptionDiv.style.display = 'none';
}
var getEl = function (id){
return document.getElementById(id);
}
var findPos = function(obj) {//计算焦点
var curleft = curtop = 0;
if (obj.offsetParent) {
curleft = obj.offsetLeft;
curtop = obj.offsetTop;
while (obj = obj.offsetParent) {
curleft += obj.offsetLeft;
curtop += obj.offsetTop;
}
}
return [curleft,curtop];
}
var setFrame = function(input){
var xy = findPos(input);
var adaptionIFrame = getEl("adaptionIFrame");
adaptionIFrame.style.display="block";
adaptionIFrame.style.left=xy[0];
adaptionIFrame.style.top=xy[1]+parseInt(input.currentStyle.height)+4;
adaptionIFrame.style.width=parseInt(input.currentStyle.width)+2;
var adaptionDiv = getEl("adaptionDiv");
adaptionDiv.style.display = "block";
adaptionDiv.style.left=xy[0];
adaptionDiv.style.top=xy[1]+parseInt(input.currentStyle.height)+4;
adaptionDiv.style.width=parseInt(input.currentStyle.width)+2;
adaptionDiv.style.height=adaptionIFrame.style.height;
var adaptionDiv_body = getEl("adaptionDiv_body");
adaptionDiv_body.style.display = "";
adaptionDiv_body.style.left=xy[0];
adaptionDiv_body.style.top=xy[1]+parseInt(input.currentStyle.height)+4;
adaptionDiv_body.style.width=parseInt(input.currentStyle.width)+2;
adaptionDiv_body.style.height=parseInt(adaptionDiv.style.height)-17;
return adaptionDiv_body;
}
/* 获取上下文根,返回如 http://localhost:xxx/xxx */
var getRootPath = function() {
var strFullPath = window.document.location.href;
var strPath = window.document.location.pathname;
var pos = strFullPath.indexOf(strPath);
var prePath = strFullPath.substring(0, pos);
var postPath = strPath.substring(0, strPath.substr(1).indexOf('/') + 1);
return (prePath + postPath);
}
this.onmousemoveLi = function(li){//斑马格颜色
li.style.backgroundColor = "#64B4DF";
}
this.onmouseoutLi = function(li){//鼠标移出时的颜色
li.style.backgroundColor = "#FFFFFF";
}
}
-----------------------------------------
测试数据(/pages/autoadaptation/autoAdaptation_data.jsp):当输入关键字“1”和“a”还有“b”时会有对应的数据对其进行自动匹配。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%
String info = request.getParameter("info");
java.util.List list = new java.util.ArrayList();
list.add("a");
list.add("ab");
list.add("abc");
list.add("abcd");
list.add("abcde");
list.add("abcdef");
list.add("abcdefg");
list.add("abcdefgh");
list.add("abcdefghi");
list.add("1");
list.add("12");
list.add("123");
list.add("1234");
list.add("12345");
list.add("123456");
list.add("1234567");
list.add("12345678");
list.add("123456789");
list.add("b");
StringBuffer res = new StringBuffer();
if(info!=null){
for(int i=0;i
res.append(";");
res.append((String)list.get(i));
}
}
}
String resStr = (res).toString();
if(resStr!=null&&resStr.length()>0){
resStr = resStr.substring(1);
}
System.out.println(resStr);
out.write(resStr.trim());
%>
-----------------------------------------
以上就是一个比较粗糙的自动匹配的功能封装,还没有做完,这只是一个最初的版本,比如说匹配时的提示窗体现在还没有实现拖拽,BAIDU和GOOGLE都能拖拽的。不过这个在企业级应用当中基本上也够用了,我封装这个就是准备用在《中国电信集团及CRM》3期上的一个小组件。效果如下图: