查了半天资料, 据说这三事件的执行顺序是:
onkeydown -> onkeypress -> onkeyup
===========================
我遇到的情况是, onkeyup的注册的方法执行异步的ajax方法, 这时好像只有onkeyup事件比较满意
在input中, 当按下一个字母键"S"时, onkeydown、onkeypress都会先执行ajax的方法, 之后才给input赋值, 造成查询结果为空.
当用onkeyup事件, 则可以捕获到"上箭头"、"下箭头"按键, 唯独捕获不了"回车键". 尝试了各种办法, 都没法完全解决, 干脆用 onkeydown事件专门处理下回车键吧
============================
代码如下: 后期加的功能, 时间赶, 又不擅长前台, 赶工写的功能, 没有很好的结构去重用代码, 以后有时间可能会整理下, 因此: 垃圾代码仅为实现功能, 见谅.
前台代码:
<td class="infoContent">
<asp:HiddenField ID="hiddenFldApplication" runat="server"/>
<div id='divAffectApplication' class='divAffectApplication' runat="server" style="word-warp:break-word;overflow-x:hidden;overflow-y:scroll;border:inset 2px;width:98%;height:50px;" onclick="inputFocus(this);">
<input type="text" style="margin-left:10px;width:120px;border: none 0px" onkeydown="checkEnterKey(event,'divPopupLayer')" onkeyup="checkKey(event,this,'divPopupLayer');">
</div>
</td>
相关后台代码:
if (aService != "")
{
aService += "<INPUT style='BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; WIDTH: 120px; MARGIN-LEFT: 10px; BORDER-TOP: 0px; BORDER-RIGHT: 0px' class=valid onkeydown=\"checkEnterKey(event,'divPopupLayer')\" onkeyup=\"checkKey(event,this,'divPopupLayer');\">";
//txtAffectServices.Text = aService;
this.divAffectService.InnerHtml = aService;
}
else
{
aApplication += "<INPUT style='BORDER-BOTTOM: 0px; BORDER-LEFT: 0px; WIDTH: 120px; MARGIN-LEFT: 10px; BORDER-TOP: 0px; BORDER-RIGHT: 0px' class=valid onkeydown=\"checkEnterKey(event,'divPopupLayer')\" onkeyup=\"checkKey(event,this,'divPopupLayer');\">";
this.divAffectApplication.InnerHtml = aApplication;
}
//一般处理程序
//handler方法获取Post的请求参数
using System; using System.Collections.Generic; using System.Linq; using System.Web; using SqlDBLib; using CommonLib; using System.Text; namespace WebSite.Common { /// <summary> /// 根据服务表返回特定格式的服务名称(如: Svr(张鹏),Svr(苏铁)) /// </summary> public class ServiceInfoHandler : IHttpHandler, System.Web.SessionState.IRequiresSessionState { public void ProcessRequest(HttpContext context) { //context.Response.Cache.SetCacheability(HttpCacheability.NoCache); //context.Response.ContentType = "text/plain"; //if ((context.Session["_userRoles"] as List<string>).Count != 0) //{ // if ((context.Session["_userRoles"] as List<string>).Contains("开发负责人") || (context.Session["_userRoles"] as List<string>).Contains("管理员")) // { // List<string> lst = ServiceDB.GetServicePrincipal(); // StringBuilder sb = new StringBuilder(); // foreach (string s in lst) // { // sb.Append(s + ","); // } // context.Response.Write(sb.ToString()); // } // else // { // context.Response.Redirect("~/Default.aspx"); // } //} //else //{ // context.Response.Redirect("~/Default.aspx"); //} context.Response.Cache.SetCacheability(HttpCacheability.NoCache); context.Response.ContentType = "text/plain"; if ((context.Session["_userRoles"] as List<string>).Count != 0) { if ((context.Session["_userRoles"] as List<string>).Contains("开发负责人") || (context.Session["_userRoles"] as List<string>).Contains("管理员")) { //获取XMLHttpRequest的Post方式中的Send发送的参数 string inputStr = ""; using (System.IO.Stream stream = context.Request.InputStream) { using (System.IO.StreamReader sr = new System.IO.StreamReader(stream)) { try { inputStr = sr.ReadToEnd(); } catch (Exception ex) { throw ex; } } } if (!string.IsNullOrEmpty(inputStr)) { //List<string> lst = ServiceDB.GetServicePrincipal(inputStr); List<string> lst = ServiceDB.GetSrvAppPrincipal(inputStr); StringBuilder sb = new StringBuilder(); foreach (string s in lst) { sb.Append(s.Replace(")",")<em style=\"display:none;\">") + "</em>,"); } context.Response.Write(sb.ToString()); } } else { context.Response.Redirect("~/Default.aspx"); } } else { context.Response.Redirect("~/Default.aspx"); } } public bool IsReusable { get { return false; } } } }
js代码:
//###Start.###==>(应用选择列表)仿hotmail收件人弹层
//增加一个onkeypress事件, 1.非ie不支持onpropertychange事件,2.onpropertychange事件用js赋值无法触发
function checkKey(eventObject, object, popUpLayerId) {
var eventObj = eventObject || window.event;
//var eventSource = eventObj.srcElement;
if ((eventObj.keyCode >= 65 && eventObj.keyCode <= 90) || (eventObj.keyCode >= 97 && eventObj.keyCode <= 122) || eventObj.keyCode == 8 || eventObj.keyCode == 46) {
showPopUpLayer(object.offsetParent, popUpLayerId);
}
var popUpLayer = window.document.getElementById(popUpLayerId);
if (popUpLayer.innerHTML != "" && popUpLayer.childNodes[0].childNodes[0].childNodes.length > 0) {
if (eventObj.keyCode == 38 || eventObj.keyCode == 40) {
switch (eventObj.keyCode) {
case 38:
moveItem(popUpLayerId, -1);
break;
case 40:
moveItem(popUpLayerId, 1);
break;
default:
}
}
}
}
//悲摧的onkeyup捕获不到回车键, 专门写个处理回车的
function checkEnterKey(eventObject, popUpLayerId) {
var eventObj = eventObject || window.event;
if (eventObj.keyCode == 13) {
moveItem(popUpLayerId, 0);
}
}
//弹出层, 该层将显示在parentElem的下方, popUpLayerId为弹层窗口的ID
function showPopUpLayer(parentElem, popUpLayerId) {
//保存txtBox原有数值及div的ID
var oldValue;
var parentElemId = parentElem.id;
for (var i = 0; i < parentElem.childNodes.length; i++) {
if (parentElem.childNodes[i].tagName == "INPUT") {
oldValue = parentElem.childNodes[i].value;
break;
}
}
//设置弹层Div的位置
var pointX = parentElem.offsetLeft;
var pointY = parentElem.offsetTop + parentElem.offsetHeight;
while (parentElem = parentElem.offsetParent) {
if (parentElem.parentNode.parentNode.tagName == 'BODY') {
break;
}
pointX += parentElem.offsetLeft;
pointY += parentElem.offsetTop;
}
var popUpLayer = window.document.getElementById(popUpLayerId);
popUpLayer.style.left = pointX + "px";
popUpLayer.style.top = pointY + "px";
popUpLayer.style.display = "block";
//异步请求
if (parentElemId == "ctl00_ContentPlaceHolder1_LeaderEvaluate1_divAffectApplication") {
AjaxApplicationInfo('../Common/ApplicationInfoHandler.ashx', oldValue, popUpLayerId);
}
if (parentElemId == "ctl00_ContentPlaceHolder1_LeaderEvaluate1_divAffectService") {
AjaxApplicationInfo('../Common/ServiceInfoHandler.ashx', oldValue, popUpLayerId);
}
}
//处理Ajax方法的返回结果的函数, 需要在Ajax方法之前被加载
function dealResponseTesxt(responseText, popUpLayerId) {
var layer = window.document.getElementById(popUpLayerId);
clearChildNodes(layer);
if (responseText != "") {
var strs = responseText.substring(0, responseText.length - 1).split(',');
var strTemp;
var innerStr = "<table style='border: 0px; width: 97%;'>";
for (var v = 0; v < strs.length; v++) {
if (strs[v].indexOf('/') != -1) {
strTemp = strs[v].split('/');
innerStr += "<tr class='popUpLayerTr' onactivate='choseApplication(this)'><td>" + strTemp[0] + "</td><td>" + strTemp[1] + "</td></tr>";
}
else {
innerStr += "<tr class='popUpLayerTr' onactivate='choseService(this)'><td>" + strs[v] + "</td></tr>";
}
}
innerStr += "</table>";
layer.innerHTML = innerStr;
}
else {
layer.style.display = "none";
}
}
//查询应用的Ajax方法
function AjaxApplicationInfo(remoteUrl, originValue, popUpLayerId) {
var xhr;
if (window.ActiveXObject) {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
else if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else {
throw new Error("Ajax is not supported by this browser");
}
//处理返回结果的方法
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
//将结果显示在弹出的新DIV上;
dealResponseTesxt(xhr.responseText, popUpLayerId);
}
}
}
xhr.open("post", remoteUrl, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(originValue);
}
//消除层, 该层
function hideApplicationList() {
window.document.getElementById("divPopupLayer").style.display = 'none';
}
//从下拉列表中, 选择应用并添加到选择列表中(选择列表ID(偷个懒): ctl00_ContentPlaceHolder1_LeaderEvaluate1_divAffectApplication)
function choseApplication(trItem) {
var divAddedto = window.document.getElementById('ctl00_ContentPlaceHolder1_LeaderEvaluate1_divAffectApplication');
var frontStr = divAddedto.innerHTML.substring(0, divAddedto.innerHTML.lastIndexOf("<INPUT"));
var rearStr = divAddedto.innerHTML.substring(divAddedto.innerHTML.lastIndexOf("<INPUT"));
divAddedto.innerHTML = frontStr + trItem.innerHTML.replace("</TD>\r\n<TD>", "/").replace("<TD>", "<SPAN>").replace("</TD>", "<font style='cursor:pointer;color:Red;border-left: solid 1px #D5D5D5;margin-left:10px;' onclick='delApplication(this.parentNode)'> x</font></SPAN>") + rearStr;
//将选择的应用信息保存到隐藏域中
var hiddenField = window.document.getElementById('ctl00$ContentPlaceHolder1$LeaderEvaluate1$hiddenFldApplication');
hiddenField.value = divAddedto.innerText.replace(/\) x/g, "),").replace(/\s/g, "");
hideApplicationList();
inputClear(divAddedto);
}
function choseService(trItem) {
var divAddedto = window.document.getElementById('ctl00_ContentPlaceHolder1_LeaderEvaluate1_divAffectService');
var frontStr = divAddedto.innerHTML.substring(0, divAddedto.innerHTML.lastIndexOf("<INPUT"));
var rearStr = divAddedto.innerHTML.substring(divAddedto.innerHTML.lastIndexOf("<INPUT"));
divAddedto.innerHTML = frontStr + trItem.innerHTML.replace("<TD>", "<SPAN>").replace("</TD>", "<font style='cursor:pointer;color:Red;border-left: solid 1px #D5D5D5;margin-left:10px;' onclick='delService(this.parentNode)'> x</font></SPAN>") + rearStr;
//将选择的应用信息保存到隐藏域中
var hiddenField = window.document.getElementById('ctl00$ContentPlaceHolder1$LeaderEvaluate1$hiddenService');
hiddenField.value = divAddedto.innerText.replace(/\) x/g, "),").replace(/\s/g, "");
hideApplicationList();
inputClear(divAddedto);
}
//点击应用DIV, 重建选择控件后, 自动将焦点移到input中 ---- 未完成
function inputFocus(parentDiv) {
for (var i = 0; i < parentDiv.childNodes.length; i++) {
if (parentDiv.childNodes[i].tagName == "INPUT") {
parentDiv.childNodes[i].focus();
break;
}
}
}
//删除应用DIV中的某一项
function delApplication(appSpan) {
var divAddedto = window.document.getElementById('ctl00_ContentPlaceHolder1_LeaderEvaluate1_divAffectApplication');
divAddedto.innerHTML = divAddedto.innerHTML.replace(appSpan.outerHTML, "");
//将选择的应用信息保存到隐藏域中
var hiddenField = window.document.getElementById('ctl00$ContentPlaceHolder1$LeaderEvaluate1$hiddenFldApplication');
hiddenField.value = divAddedto.innerText.replace(/\) x/g, "),").replace(/\s/g, "");
}
//删除服务DIV中的某一项
function delService(srvSpan) {
var divAddedto = window.document.getElementById('ctl00_ContentPlaceHolder1_LeaderEvaluate1_divAffectService');
divAddedto.innerHTML = divAddedto.innerHTML.replace(srvSpan.outerHTML, "");
//将选择的应用信息保存到隐藏域中
var hiddenField = window.document.getElementById('ctl00$ContentPlaceHolder1$LeaderEvaluate1$hiddenService');
hiddenField.value = divAddedto.innerText.replace(/\) x/g, "),").replace(/\s/g, "");
}
//插入结束, 清除输入框的值
function inputClear(parentDiv) {
for (var i = 0; i < parentDiv.childNodes.length; i++) {
if (parentDiv.childNodes[i].tagName == "INPUT") {
parentDiv.childNodes[i].value = "";
break;
}
}
}
//请空节点中的子节点
function clearChildNodes(parentElem) {
var i = 0;
while (i < parentElem.childNodes.length) {
parentElem.removeChild(parentElem.childNodes[i]);
i++;
}
}
//在弹出的下拉层中, 移动节点的方法
function moveItem(popUpLayerId, offset) {
var popUpLayer = window.document.getElementById(popUpLayerId);
//alert(ShowObjct(popUpLayer));
if (popUpLayer.innerHTML != "" && popUpLayer.childNodes[0].childNodes[0].childNodes.length > 0) {
var index = -1;
var nodes = popUpLayer.childNodes[0].childNodes[0].childNodes;
for (var v = 0; v < nodes.length; v++) {
if (nodes[v].tagName == "TR" && nodes[v].className == 'popUpLayerChosenTr') {
index = v;
break;
}
}
if (index == -1) {
nodes[0].className = "popUpLayerChosenTr";
index = 0;
}
else if (index == 0 && offset < 0) {
}
else if (index == nodes.length - 1 && offset > 0) {
}
else {
nodes[index].removeAttribute("className");
nodes[index + offset].className = "popUpLayerChosenTr";
popUpLayer.scrollTop = nodes[index + offset].offsetTop - nodes[index + offset].clientHeight;
}
//执行选中操作
if (offset == 0 && nodes[index].innerHTML != "") {
nodes[index].onactivate();
}
}
}
//###End.###==>应用选择列表