【问题标题】:Capturing onkeydown in Javascript在 Javascript 中捕获 onkeydown
【发布时间】:2010-07-20 00:39:13
【问题描述】:

我有一个 AS/400 CGI 应用程序的 Web 前端,它允许使用一些 F1-F24 键(取决于页面)作为以及向上翻页、向下翻页等 - 这些被传递给适当处理它们的底层应用程序。例如,在给定的页面上,用户可以按下 F3 按钮或按下 F3 键 - 它们都会将(隐藏的)CmdKey 变量设置为'_K03' 的名称和 'F03' 的值。按钮处理很简单,没有问题。为了处理用户在键盘上按下实际 F 键,我有一个兼容 IE 的脚本很长时间了,它运行良好:

function setCmdKeyIE() {                                                        
  var cmdkeycode = "";                                                          
  if (window.event.keyCode != 13 &
    window.event.keyCode != 33 &                 
    window.event.keyCode != 34 &
    window.event.keyCode < 112 ) return;         
  window.event.keyCode = window.event.keyCode + 1000;                           
  if (window.event.shiftKey) window.event.keyCode = window.event.keyCode + 1000;
  switch(window.event.keyCode) {                                                
    case 1013: cmdkeycode = "EN"; break; /* Enter */                            
    case 1033: cmdkeycode = "UP"; break; /* Page Up */                          
    case 1034: cmdkeycode = "DN"; break; /* Page Down  */                       
    case 1112: cmdkeycode = "01"; break; /* F1 */                               
    case 1113: cmdkeycode = "02"; break; /* F2 */                               
    ...(F3 thru F24 here)...
    default:   return;                   /* Anything else should be ignored */
  }                                                         
  window.event.cancelBubble = true;                         
  window.event.returnValue = false;                         
  document.forms[0].CmdKey.value = "F" + cmdkeycode;        
  document.forms[0].CmdKey.name = "_K" + cmdkeycode;        
  if (ONSUBMITFUN() == true) document.forms[0].submit();    
}                                                           

这不仅正确设置了 CmdKey 元素,而且还覆盖(停止)浏览器默认行为(如果有)被执行(例如,当用户按 F3 时,搜索框不会出现)。

setCmdKeyIE() 函数是这样调用的:

<body onKeyDown="setCmdKeyIE();" onHelp="return false;">

我现在需要它来为 Firefox(以及可能的其他浏览器)工作,但我遇到了各种各样的麻烦。我最初更改了 setCmdKeyIE 函数(是的,我知道名称一旦不再特定于 IE 就应该更改,但这是我最不担心的!)以获取事件作为参数(仅适用于 Firefox,我想)或使用当前行为,如果它没有通过(使用 IE)。我还添加了一些其他处理来阻止 Firefox 事件传播,但它不起作用...

这是新的非工作代码 - 哪位好心人能指出我的方法的错误吗?

function setCmdKey(e) {
  if (!e) {
    var e = window.event; /* IE event-handling */
  }
  var wrkkeyCode = e.keyCode;
  if (wrkkeyCode != 13 &
      wrkkeyCode != 33 &
      wrkkeyCode != 34 &
      wrkkeyCode != 27 &
      wrkkeyCode < 112 ) return;
  wrkkeyCode = wrkkeyCode + 1000;
  if (e.shiftKey) wrkkeyCode = wrkkeyCode + 1000;
  var cmdkeycode = "";
  switch(wrkkeyCode) {
    case 1013: cmdkeycode = "EN"; break; /* Enter */
    case 1033: cmdkeycode = "UP"; break; /* Page Up */
    case 1034: cmdkeycode = "DN"; break; /* Page Down  */
    case 1112: cmdkeycode = "01"; break; /* F1 */
    case 1113: cmdkeycode = "02"; break; /* F2 */
    ...(F3 thru F24 here)...
    default:   return;               /* Anything else should be ignored */
  }
  if (e.stopPropagation) {           /* FF */
    e.stopPropagation();
    e.preventDefault();
  }
  else {                             /* IE */
    e.cancelBubble = true;
    e.returnValue = false;
  }
  document.forms[0].CmdKey.value = "F" + cmdkeycode;
  document.forms[0].CmdKey.name = "_K" + cmdkeycode;
  if (ONSUBMITFUN() == true) document.forms[0].submit();
}

我需要使用 Firefox 从 setCmdKeyIE 返回 false 吗?即使这个过程返回假,这是否成立?

【问题讨论】:

标签: javascript cross-browser dom-events ibm-midrange onkeydown


【解决方案1】:

更新

我现在已经解决了这个问题。很抱歉删除了下面 cmets 的上下文,但是,嘿,以前的版本仍然存在。

原来在IE中有两个问题需要解决:首先是和我之前说的相反,在&lt;body&gt;里面放一个onkeydown属性是行不通的。您需要将其附加到文档中。第二个问题是 IE 不会让您抑制魔术行为,例如由 F3 键触发的搜索对话框,除非您进行了涉及更改 keydown 事件的 keyCode 属性的邪恶黑客行为,这显然是非常错误的事情.尽管如此,删除&lt;body&gt; 中的onkeydown 属性,以下应该可以完成这项工作(现在修改为也可以在Opera 中工作):

var keyCodeMap = {
    "1013": "EN",
    "1033": "UP",
    "1034": "DN",
    "1112": "01",
    "1113": "02",
    "1114": "03"
    // ...(F4 thru F24 here)...
};

var suppressKeypress = false;

function setCmdKey(e) {
    e = e || window.event;
    var wrkkeyCode = e.keyCode;
    if (wrkkeyCode != 13 &&
        wrkkeyCode != 33 &&
        wrkkeyCode != 34 &&
        wrkkeyCode != 27 &&
        wrkkeyCode < 112) return;

    wrkkeyCode += 1000;

    if (e.shiftKey) wrkkeyCode += 1000;
    var cmdkeycode = keyCodeMap[wrkkeyCode];
    if (!cmdkeycode) return; /* Anything else should be ignored */

    var input = document.forms[0].elements["CmdKey"];
    input.value = "F" + cmdkeycode;
    input.name = "_K" + cmdkeycode;

    try {
        // Prevent default action in IE by bad hacky means
        e.keyCode = 0;
    } catch (ex) {
        // Other browsers do not allow setting the keyCode
    }
    suppressKeypress = true;

    if (ONSUBMITFUN()) document.forms[0].submit();
    return false;
}

document.onkeydown = setCmdKey;
document.onkeypress = function() {
    if (suppressKeypress) {
        return false;
    }
};

【讨论】:

  • @Tim,我还是需要通过cancelBubble来停止IE事件处理,否则IE默认事件仍然发生(除了正在提交的页面)。
  • 哪个键?我很好奇,因为我没想到会是这样。
  • 在 IE 中,如果我使用您的脚本并按例如F3,页面未提交 - 显示搜索框。我没有在 FF 中检查过你的脚本——我首先检查了 IE 的向后兼容性。我的假设是,因为这个脚本提交了页面,所以它永远不会到达最终的“return false”语句——可能是这样吗?
  • 可能就是这样。我会做一些研究。
  • 在 Opera 中,您无法抑制默认操作 onkeydown,您必须使用 onkeypress 才能这样做。另请参阅 Jan Wolter 的 JavaScript Madness: Keyboard Events
【解决方案2】:

即使您通过修改事件阻止了默认设置,您也应该始终从事件处理程序返回 false,有关详细信息,请参阅 Quirks mode

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 2012-08-26
    • 1970-01-01
    • 2012-01-27
    • 2017-12-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多