Rocho.J

人脑是不可靠的, 随时记录感悟并且经常重复!

 

仿hotmail收件人弹层: onkeyup事件无法捕获到"回车按键", 用onkeydown事件捕获额外处理"回车键"

查了半天资料, 据说这三事件的执行顺序是:

onkeydown  ->  onkeypress  ->  onkeyup

 

===========================

我遇到的情况是, onkeyup的注册的方法执行异步的ajax方法, 这时好像只有onkeyup事件比较满意

在input中, 当按下一个字母键"S"时, onkeydown、onkeypress都会先执行ajax的方法, 之后才给input赋值, 造成查询结果为空.

当用onkeyup事件, 则可以捕获到"上箭头"、"下箭头"按键, 唯独捕获不了"回车键". 尝试了各种办法, 都没法完全解决, 干脆用  onkeydown事件专门处理下回车键吧

 

============================

代码如下:  后期加的功能, 时间赶, 又不擅长前台, 赶工写的功能,  没有很好的结构去重用代码, 以后有时间可能会整理下, 因此: 垃圾代码仅为实现功能, 见谅.

前台代码:

View Code
<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>

 

相关后台代码:

View Code
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;
            }
        }
    }
}
View Code

 

 

 

js代码:

View Code
//###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)'>&nbsp;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)'>&nbsp;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.###==>应用选择列表

 

 

posted on 2011-11-16 16:55  RJ  阅读(2045)  评论(0编辑  收藏  举报

导航