zoukankan      html  css  js  c++  java
  • 仿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;98%;height:50px;" onclick="inputFocus(this);">
    <input type="text" style="margin-left:10px;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; 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.###==>应用选择列表
  • 相关阅读:
    树莓派设置CPU运行的核心数为3,保留核心4号
    node+egg中mongdb的一些知识点
    如何提高前端的技能和快速涨薪?
    【安全认证】我的CISSP达成之路
    前端gitLab ci/cd搭建
    flutter调试
    js rgb hex hsv色值转换
    Error waiting for a debug connection: The log reader stopped unexpectedly
    Flutter滑动列表实现
    前端异常监控
  • 原文地址:https://www.cnblogs.com/cs_net/p/2251473.html
Copyright © 2011-2022 走看看