类似google搜索提示支持键盘应用

代码从一位论坛老兄铁木箱子那里学来的,下面是记录一下自己用起来的方法。

首先建立一个js内容如下



/**
* Desc:该JS需要先导入../common/base.js
*/

/**
* 说明:
* 服务器返回的XML数据流要是如下的格式:
* <?xml version="1.0" encoding="gbk"?>
* <root>
* <nodeName>条目一</nodeName>
* <nodeName>条目二</nodeeName>
* <nodeName>条目三</nodeName>
* </root>
* 上面的nodeName就是search中的nodeName参数。
*/

function createXMLHttpRequest(){
if(window.XMLHttpRequest) {
XMLHttpReq = new XMLHttpRequest();
}
else if(window.ActiveXObject) {
try {
XMLHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
XMLHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}
return XMLHttpReq;
}

var JSearcher = {

xmlHttp : null, // xmlHttpRequest对象
randName : 'jrandnum', // 随机码的参数名称
_popup : null, // 提示框对象
_mouseOverColor : '#29cea3', // 鼠标悬停时的背景颜色
_mouseOutColor : 'white', // 鼠标离开时的背景颜色
_bgColor : 'white', // 条目显示区的背景色
_tmpURL : '', // 上一个请求的地址
_tmpKey : '', // 上一次请求的关键字
_srcElt : null, // 触发时间的HTML元素
_tbodyID : '_$jst@#_$', // 条目的表格体唯一ID

/**
* Desc:搜索的开始方法.附加该方法到指定input或textarea的onkeypress事件上即可。
* Para:urlStr 请求地址
* inputObj 输入框对象
* triggerKey 触发搜索的按键,比如说'a'。不设定将所有的按键都触发,
* 可以设置为null或''
* searchNum 需要显示的最多搜索条目数
* nodeName XML数据流中的节点名称
*/
search:function(urlStr, inputObj, triggerKey, searchNum, nodeName)
{

// 触发键控制,只有在输入框中按此键时才触发搜索查询
if (triggerKey != null && (typeof(triggerKey) == 'string' && triggerKey != '')) {
if (event.keyCode != triggerKey.charCodeAt(0))return;
}

if (inputObj == null || typeof(inputObj) != 'object') {
alert("Error: the object you set to parameter 'inputobj' is null!");
return;
}

// 过滤回车选定重复显示的问题
if (event.keyCode == 13) return;

// 对同一地址,同一关键字不进行第二次请求
if (this._tmpURL == urlStr && this._tmpKey == inputObj.value) {
this._showPopup();
return;
} else {
this._tmpURL = urlStr;
this._tmpKey = inputObj.value;
}

// 设定触发该事件的源元素
this._srcElt = window.event.srcElement;



// 附加控制
var keypressFunc = inputObj.onkeydown;
inputObj.onkeydown = function() {
JSearcher._selectKeys(inputObj);
//if (typeof(keypressFunc) == 'function') keypressFunc();
}

// 发送请求

if (this.xmlHttp == null) this.xmlHttp = createXMLHttpRequest();

if (this.xmlHttp.readyState !=0 || this.xmlHttp.readyState != 4) {

this.xmlHttp.abort();
}

try{
with (this.xmlHttp) {
// 加随机数防止缓存
if (urlStr.indexOf("?") == -1) urlStr += "?";
else urlStr += "&";
urlStr += this.randName + Math.random() + "=" + Math.random();


// 发送请求
onreadystatechange = function (){
//alert(JSearcher.xmlHttp);
if (JSearcher.xmlHttp.readyState == 4 && JSearcher.xmlHttp.status == 200) {

JSearcher._JparseSearch(JSearcher.xmlHttp, inputObj, searchNum, nodeName);
}
}
open("POST", urlStr, true);
setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
send(null);
}
} catch (ex) {
alert(ex);
}

},

/**
* Desc:设置全局变量属性
* Para:attrName 要设置的属性名称
* attrValue 要设置的属性的值
*/
setGlobal:function(attrName, attrValue)
{
if (typeof(attrName) == 'undefined' || typeof(attrValue) == 'undefined') return;
switch (attrName) {
case 'selectedColor' : this._mouseOverColor = attrValue;break;
case 'unSelectedColor' : this._mouseOutColor = attrValue;break;
case 'bgColor' : this._bgColor = attrValue;break;
}
},

/**
* Desc:解析服务器返回的XML数据流
* Para:myXMLHttp xmlHttpRequest对象
* obj input框对象
* searchNum 搜索结果显示的最大条目数
* nodeName XML数据流中指定节点的名称
*/
_JparseSearch:function(myXMLHttp, obj, searchNum, nodeName)
{
if (myXMLHttp == null) {
alert("Error: the xmlHttpRequest is null!");
return;
}
var xmlStream = myXMLHttp.responseXML;
if (xmlStream == null) {
alert("Error: the xml stream from server is null!");
return;
}
var slist = xmlStream.getElementsByTagName(nodeName);
if (slist.length < 1) return;
if (obj.id == '') obj.id = '_$my#g' + Math.random();
this._tbodyID = this._tbodyID + Math.random();
var htmlStr = "<table width='100%' height='100%' border='0' cellspacing='0'"
+ " cellpadding='0' style='filter:alpha(opacity=80);"
+ "font-size:12px;'><tbody id='" + this._tbodyID + "'>";
for ( var i = 0 ; i < slist.length ; i ++) {
var et = slist.item(i);

if (i == searchNum) break;
if (!et.hasChildNodes()) continue;
htmlStr += "<tr οnmοuseοut=\"this.style.backgroundColor='"
+ this._mouseOutColor + "'\" "
+ "οnmοuseοver=\"this.style.backgroundColor='"
+ this._mouseOverColor + "'\"><td height='20' "
+ "οnclick='JSearcher._setValue(\"" + obj.id + "\",\""
+ et.firstChild.nodeValue + "\")'>"
+ et.firstChild.nodeValue + "</td></tr>";
}
htmlStr += "</tbody></table>";
this._initPopup(obj, htmlStr);
this._showPopup();
},

/**
* Desc:按键操作检测
* Para:obj input输入框对象
*/
_selectKeys:function(obj)
{
if ( this._popup.style.display == "none") return;

var code = event.keyCode;
var curRowIndex = 0;

var tbody = document.getElementById(this._tbodyID);
if (tbody != null && tbody.rows.length >= 1) {
var et = null;
for (var i = 0 ; i < tbody.rows.length ; i++) {
et = tbody.rows[i];
if (et.style.backgroundColor == this._mouseOverColor) {
curRowIndex = i;
break;
}
}
if (code == 38) { // 上箭头
tbody.rows[curRowIndex].style.backgroundColor = this._mouseOutColor;
if (curRowIndex == 0) {
tbody.rows[tbody.rows.length-1].style.backgroundColor = this._mouseOverColor;
} else {
tbody.rows[curRowIndex - 1].style.backgroundColor = this._mouseOverColor;
}
}
if (code == 40) { // 下箭头
tbody.rows[curRowIndex].style.backgroundColor = this._mouseOutColor;
if (curRowIndex == tbody.rows.length-1) {
tbody.rows[0].style.backgroundColor = this._mouseOverColor;
} else {
tbody.rows[curRowIndex + 1].style.backgroundColor = this._mouseOverColor;
}
}
if (code == 13 && et != null) { // 回车键
this._setValue(obj.id, et.childNodes[0].firstChild.nodeValue);
}
}
},

/**
* Desc:设定选中的值到输入框中
* Para:objID 输入框对象的唯一ID
* sval 被选中的值
*/
_setValue:function(objID, sval)
{
var inputObj = document.getElementById(objID);
if (inputObj != null) {
inputObj.value = sval;
this._hidePopup();
inputObj.focus();
}
},

/**
* Desc:初始化提示框
* Para:obj input输入框对象
* htmlStr DIV中的HTML数据代码
*/
_initPopup:function(obj, htmlStr)
{
if (this._popup == null) {
this._popup = document.createElement("div");
this._popup.id = "_$myJSearcherID" + Math.random();
this._popup.style.display = "none";
this._popup.style.zIndex = "100";
this._popup.style.border="solid black 1px";
this._popup.style.position = "absolute";
this._popup.style.backgroundColor = this._bgColor;
document.body.appendChild(this._popup);
}

// 定位控制
var _objXY = this._srcElt.getBoundingClientRect(); // 确定触发源的真实位置

var _win = window;
var _top = window;
while(_top.parent.document != _top.document){
_top = _top.parent;
}
var _leftM = _win.screenLeft - _top.screenLeft + 2; // 偏移量
var _topM = _win.screenTop - _top.screenTop + 2;
_leftM = _leftM == 2 ? 0 : _leftM;
_topM = _topM == 2 ? 0 : _topM;

var _divTop = _top.document.body.scrollTop + _topM + _objXY.bottom;
var _divLeft = _top.document.body.scrollLeft + _leftM + _objXY.left;
var _winSize = this._getClientWidthHeight(_top);
if((_divTop + this._popup.offsetHeight >= _winSize._height) &&
(_winSize._height - _divTop <= _divTop-this._srcElt.offsetHeight)) {
_divTop -= this._popup.offsetHeight - this._srcElt.offsetHeight - 3;
}

//this._popup.style.top = _divTop;
// this._popup.style.width = _objXY.right - _objXY.left;
//this._popup.style.left = _divLeft;
this._popup.style.width=obj.offsetWidth + "px";
var left = this._calculateOffset(obj, "offsetLeft");
var top = this._calculateOffset(obj, "offsetTop") + obj.offsetHeight;
this._popup.style.border = "black 1px solid";
this._popup.style.left = left + "px";
this._popup.style.top = top + "px";
//alert("---top--"+this._popup.style.top+"---width--"+this._popup.style.width+"---left--"+this._popup.style.left);
this._popup.innerHTML = htmlStr;
},

/**
* Desc:显示提示框
*/
_showPopup:function()
{
if (this._popup != null) {
this._popup.style.display = "";
}
},

/**
* Desc:隐藏提示框
*/
_hidePopup:function()
{
if (this._popup != null) {
this._popup.style.display = "none";
}
},

/**
* Desc:取得客户端屏幕的宽度和高度信息
*/
_getClientWidthHeight:function(win)
{
if(win==null){win=window;}
var cw = win.document.getElementsByTagName("html")[0].clientWidth;
var ch = win.document.getElementsByTagName("html")[0].clientHeight;
cw = (cw>0) ? cw : win.document.body.clientWidth;
ch = (ch>0) ? ch : win.document.body.clientHeight;
return {'_width':cw, '_height':ch};
},

/**
* Desc:计算显示位置
*/
_calculateOffset:function(field, attr){
var offset = 0;
while(field) {
offset +=field[attr];
field = field.offsetParent;
}
return offset;
}
};

window.document.onclick = function()
{
JSearcher._hidePopup();
}

只需在jsp页面引入上面js即可
jsp代码如下注意返回的提示信息要是xml

<%@ page contentType="text/html; charset=UTF-8" language="java" %>
<%
String contextpath = request.getContextPath();
response.setHeader("Pragma", "No-cache");
response.setHeader("Cache-Control", "no-cache");
response.setDateHeader("Expires", 0);
%>
<html>
<head>
<title>模拟google输入提示</title>
<META http-equiv=Content-Type content="text/html; charset=UTF-8">
<!--这里需要引入一个Base.js和上面我们创建的js(autosearch.js)-->
<script type="text/javascript" src="<%=contextpath%>/script/Base.js"></script>
<script type="text/javascript" src="<%=contextpath%>/script/autosearch.js"></script>
<script type="text/javascript" src="<%=contextpath%>/script/testzw.js"></script>
</head>
<script language="javascript">



</script>

<body leftmargin="0" topmargin="0">
<table style="BORDER-COLLAPSE: collapse" borderColor="#111111" cellspacing="0" cellpadding="2" width="400" bgcolor="#f5efe7" border="0">
<tr>
<td align="middle" bgcolor="#dbc2b0" height="19" colspan="3">
<b>商品信息搜索</b>
</td>
</tr>
<tr>
<td height="20">
输入品牌关键字:
</td>
<td align="center">
<!-- 这里是调用方法:具体参数涵义参考上面js说明 -->
<input type="text" size="15" id="names" οnkeyup="JSearcher.search('ConsumeCheckin.shtml?flag=yoyo&usercode='+this.value,this,'',10,'res')" style="height:20">

</td>

</tr>

</table>
</body>
</html>



声明 代码是借来并非原创,写这篇文章的目的让大家知道怎么用起来
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值