在JavaScript中从KeyCode获取字符值...然后修剪

171

这是我现在的代码:

$("input").bind("keydown",function(e){
    var value = this.value + String.fromCharCode(e.keyCode);
}
如果 e.keyCode 可能不是 ASCII 字符(如 Altbackspacedelarrows 等等)...
我现在需要以某种方式(最好是编程方式,而不是查找表格)从 value 中切除这些值。
我正在使用 jQuery。
我必须使用 keydown 事件。对于我需要捕获的某些按键(如 Escdelbackspace 等),keyPress 不起作用。
我不能使用 setTimeout 来获取输入的值。 setTimeout(function(){},0) 太慢了。

11
你必须使用keydown来捕获字符代码?那将是一场噩梦:http://www.quirksmode.org/js/keys.html(提示:**请使用`keypress`!!**) - Crescent Fresh
1
字符的大小写不重要。我需要至少在FF和IE中捕捉键盘上的上、下、左、右、esc、del和退格键,所以按键事件并不适用。谢谢你的提示!:-) - David Murdoch
作为对这个问题的回应,我刚刚编写了一个 jQuery 插件:https://github.com/bpeacock/key-to-charCode/。它可能有些粗糙,并且可能需要更好地与 jQuery 集成,但这是一个开始。 - Brian Peacock
1
对于任何试图解决 KeyCode 问题但实际上只想查看按下的键是什么的人,请查看此答案。简而言之:document.onkeydown = function(e){ console.log('Key: ' + e.key); } - user1717828
根据MDN(https://developer.mozilla.org/en-US/docs/Web/API/Element/keypress_event),“keypress”已被弃用,不应再使用。您应该始终使用“keydown”代替。现在,“keydown”传递“key”,它“返回表示事件所表示的键的键值的字符串。”-这与“keypress”以前所做的类似。在MDN上阅读有关“keydown”事件的更多信息:https://developer.mozilla.org/en-US/docs/Web/API/Element/keydown_event - OOPS Studio
10个回答

208
在我的经验中,String.fromCharCode(e.keyCode) 是不可靠的。String.fromCharCode 期望一个 Unicode 字符编码作为参数;e.keyCode 返回 JavaScript 按键码。JavaScript 按键码和 Unicode 字符编码是不一样的!特别地,数字键盘键返回与普通数字键不同的 keycode(因为它们是不同的键),而相同的 keycode 被用于表示大写字母和小写字母(你按下同一个键),尽管它们有不同的charcodes

例如,普通数字键 1 生成的事件具有 keycode 49,而数字键盘上的 1(打开了 Numlock)生成的 keycode 是 97。如果使用 String.fromCharCode,我们得到以下结果:

String.fromCharCode(49) returns "1"
String.fromCharCode(97) returns "a"

String.fromCharCode接受Unicode字符码,而非JavaScript按键码。按下键盘上的 a 会生成一个带有 keycode 值为65 的事件,不论生成的字符的大小写(在事件中也有一个修饰符来表示是否按下了 Shift 等键)。字符 a 具有Unicode charcode 值为61,而字符 A 具有 charcode 值为41(例如,根据http://www.utf8-chartable.de/)。但是,这些都是hex值,将它们转换为十进制,我们得到“A”的charcode值为65,“a”的值为97。[1] 这与我们从这些值获得的String.fromCharCode一致。

我的要求仅限于处理数字和普通字母(根据字符串中的位置接受或拒绝),让控制字符(F-键、Ctrl-某些键)通过。因此,我可以检查控制字符,如果不是控制字符,则针对范围进行检查,然后只需要获取实际字符。考虑到我不关心大小写(我无论如何都会将所有字母大写),并且已经限制了按键码的范围,我只需要关心数字键盘上的键。以下代码足以实现:

String.fromCharCode((96 <= key && key <= 105)? key-48 : key)
更普遍地说,一个从charcode可靠返回字符的函数会很棒(或许作为一个jQuery插件),但是我现在没有时间写。抱歉。
如果你正在使用jQuery,我还想提到e.which,它规范了e.keyCodee.charCode,这样你就不用担心按下了什么样的键了。与String.fromCharCode结合使用的问题仍然存在。
[1] 有一段时间我很困惑 - 所有的文档都说String.fromCharCode期望一个Unicode charcode,但实际上它似乎可以处理ASCII charcodes,但我认为这是因为需要将十六进制转换为十进制,再加上ASCII charcodes和普通拉丁字母的Unicode十进制charcodes有重叠之处。

2
这个评论基本上解决了我所有的问题。对我来说,令人惊奇的是jQuery没有实现一个类似于JavaScript的"String.fromCharCode"的"fromKeyCode"等效函数。 - Chris J
31
似乎是KeyPress事件可以实现这个功能。请参考https://dev59.com/i2ox5IYBdhLWcg3wNRxj#9350415。根据jQuery文档,“注意,keydown和keyup提供一个表示哪个键被按下的代码,而keypress表示输入了哪个字符。例如,小写字母“a”将在keydown和keyup事件中报告为65,但在keypress事件中报告为97。“因为这种区别,当捕获特殊按键(如箭头键)时,.keydown()或.keyup()是更好的选择。” - Adam
对于那些沉迷于 keydown 的人来说,这是非常不愉快的。 - Isaac Bolinger
关于ASCII和Unicode的最后一点说明。Unicode将所有128个ASCII字符放在同一个位置。这是有意为之的,以便任何最初使用ASCII编码的文件可以伪装成(并转换为)Unicode,无需任何工作。但扩展的ASCII字符不在同一个位置,如果你使用了那些字符,那就没办法了。 - DanielM
1
keyCode 的作用是知道按下了哪个键,而不是知道要使用哪个字符。例如,在 Dvorak 键盘上,“U” 与 QWERTY 键盘上的“F” 或韩语键盘上的“ㄹ” 具有相同的 keycode。重点不是将其转换为字符,而是使您可以轻松地将事物映射到键盘位置。 - Vincent McNabb

170

也许我没有正确理解问题,但是如果您想捕获两个输入,难道不能使用 keyup 吗?

$("input").bind("keyup",function(e){
    var value = this.value + String.fromCharCode(e.keyCode);
});

14
这在ASCII范围之外的其他语言环境下是行不通的(例如latin-1,比如德语、法语、意大利语和西班牙语)。显然,对于不可打印的按键也无法实现。 - Florian Bösch
9
使用数字键盘时,这也会失败,e.keyCode不是ASCII码(甚至不是UTF-x码)。 - Tom Chiverton
2
糟糕的答案,它甚至不能处理基本字符。例如分号keyCode是186,在其上运行String.fromCharCode()将得到垃圾。问题在于keyCode并非对于所有字符都对应于ASCII。分号的ASCII字符为59。每个特殊字符都存在相同的问题,keyCode不会返回正确的代码以供String.fromCharCode()使用。 - Alexander Tsepkov

94

按键码索引的易读键名

由于按键码相对较少,因此我将所有对应值列在静态数组中,以便可以使用keyboardMap[65]将数字65简单地转换为A

并非所有按键码都映射到可打印字符,因此返回一些其他可识别的字符串。

您可能需要修改数组以适应您的需求,并可以简单地返回空字符串以忽略您不想翻译的所有字符。 以下数组使我能够快速而可靠地确定在任何环境中按下了哪个键。 享受吧!

// names of known key codes (0-255)

var keyboardMap = [
  "", // [0]
  "", // [1]
  "", // [2]
  "CANCEL", // [3]
  "", // [4]
  "", // [5]
  "HELP", // [6]
  "", // [7]
  "BACK_SPACE", // [8]
  "TAB", // [9]
  "", // [10]
  "", // [11]
  "CLEAR", // [12]
  "ENTER", // [13]
  "ENTER_SPECIAL", // [14]
  "", // [15]
  "SHIFT", // [16]
  "CONTROL", // [17]
  "ALT", // [18]
  "PAUSE", // [19]
  "CAPS_LOCK", // [20]
  "KANA", // [21]
  "EISU", // [22]
  "JUNJA", // [23]
  "FINAL", // [24]
  "HANJA", // [25]
  "", // [26]
  "ESCAPE", // [27]
  "CONVERT", // [28]
  "NONCONVERT", // [29]
  "ACCEPT", // [30]
  "MODECHANGE", // [31]
  "SPACE", // [32]
  "PAGE_UP", // [33]
  "PAGE_DOWN", // [34]
  "END", // [35]
  "HOME", // [36]
  "LEFT", // [37]
  "UP", // [38]
  "RIGHT", // [39]
  "DOWN", // [40]
  "SELECT", // [41]
  "PRINT", // [42]
  "EXECUTE", // [43]
  "PRINTSCREEN", // [44]
  "INSERT", // [45]
  "DELETE", // [46]
  "", // [47]
  "0", // [48]
  "1", // [49]
  "2", // [50]
  "3", // [51]
  "4", // [52]
  "5", // [53]
  "6", // [54]
  "7", // [55]
  "8", // [56]
  "9", // [57]
  "COLON", // [58]
  "SEMICOLON", // [59]
  "LESS_THAN", // [60]
  "EQUALS", // [61]
  "GREATER_THAN", // [62]
  "QUESTION_MARK", // [63]
  "AT", // [64]
  "A", // [65]
  "B", // [66]
  "C", // [67]
  "D", // [68]
  "E", // [69]
  "F", // [70]
  "G", // [71]
  "H", // [72]
  "I", // [73]
  "J", // [74]
  "K", // [75]
  "L", // [76]
  "M", // [77]
  "N", // [78]
  "O", // [79]
  "P", // [80]
  "Q", // [81]
  "R", // [82]
  "S", // [83]
  "T", // [84]
  "U", // [85]
  "V", // [86]
  "W", // [87]
  "X", // [88]
  "Y", // [89]
  "Z", // [90]
  "OS_KEY", // [91] Windows Key (Windows) or Command Key (Mac)
  "", // [92]
  "CONTEXT_MENU", // [93]
  "", // [94]
  "SLEEP", // [95]
  "NUMPAD0", // [96]
  "NUMPAD1", // [97]
  "NUMPAD2", // [98]
  "NUMPAD3", // [99]
  "NUMPAD4", // [100]
  "NUMPAD5", // [101]
  "NUMPAD6", // [102]
  "NUMPAD7", // [103]
  "NUMPAD8", // [104]
  "NUMPAD9", // [105]
  "MULTIPLY", // [106]
  "ADD", // [107]
  "SEPARATOR", // [108]
  "SUBTRACT", // [109]
  "DECIMAL", // [110]
  "DIVIDE", // [111]
  "F1", // [112]
  "F2", // [113]
  "F3", // [114]
  "F4", // [115]
  "F5", // [116]
  "F6", // [117]
  "F7", // [118]
  "F8", // [119]
  "F9", // [120]
  "F10", // [121]
  "F11", // [122]
  "F12", // [123]
  "F13", // [124]
  "F14", // [125]
  "F15", // [126]
  "F16", // [127]
  "F17", // [128]
  "F18", // [129]
  "F19", // [130]
  "F20", // [131]
  "F21", // [132]
  "F22", // [133]
  "F23", // [134]
  "F24", // [135]
  "", // [136]
  "", // [137]
  "", // [138]
  "", // [139]
  "", // [140]
  "", // [141]
  "", // [142]
  "", // [143]
  "NUM_LOCK", // [144]
  "SCROLL_LOCK", // [145]
  "WIN_OEM_FJ_JISHO", // [146]
  "WIN_OEM_FJ_MASSHOU", // [147]
  "WIN_OEM_FJ_TOUROKU", // [148]
  "WIN_OEM_FJ_LOYA", // [149]
  "WIN_OEM_FJ_ROYA", // [150]
  "", // [151]
  "", // [152]
  "", // [153]
  "", // [154]
  "", // [155]
  "", // [156]
  "", // [157]
  "", // [158]
  "", // [159]
  "CIRCUMFLEX", // [160]
  "EXCLAMATION", // [161]
  "DOUBLE_QUOTE", // [162]
  "HASH", // [163]
  "DOLLAR", // [164]
  "PERCENT", // [165]
  "AMPERSAND", // [166]
  "UNDERSCORE", // [167]
  "OPEN_PAREN", // [168]
  "CLOSE_PAREN", // [169]
  "ASTERISK", // [170]
  "PLUS", // [171]
  "PIPE", // [172]
  "HYPHEN_MINUS", // [173]
  "OPEN_CURLY_BRACKET", // [174]
  "CLOSE_CURLY_BRACKET", // [175]
  "TILDE", // [176]
  "", // [177]
  "", // [178]
  "", // [179]
  "", // [180]
  "VOLUME_MUTE", // [181]
  "VOLUME_DOWN", // [182]
  "VOLUME_UP", // [183]
  "", // [184]
  "", // [185]
  "SEMICOLON", // [186]
  "EQUALS", // [187]
  "COMMA", // [188]
  "MINUS", // [189]
  "PERIOD", // [190]
  "SLASH", // [191]
  "BACK_QUOTE", // [192]
  "", // [193]
  "", // [194]
  "", // [195]
  "", // [196]
  "", // [197]
  "", // [198]
  "", // [199]
  "", // [200]
  "", // [201]
  "", // [202]
  "", // [203]
  "", // [204]
  "", // [205]
  "", // [206]
  "", // [207]
  "", // [208]
  "", // [209]
  "", // [210]
  "", // [211]
  "", // [212]
  "", // [213]
  "", // [214]
  "", // [215]
  "", // [216]
  "", // [217]
  "", // [218]
  "OPEN_BRACKET", // [219]
  "BACK_SLASH", // [220]
  "CLOSE_BRACKET", // [221]
  "QUOTE", // [222]
  "", // [223]
  "META", // [224]
  "ALTGR", // [225]
  "", // [226]
  "WIN_ICO_HELP", // [227]
  "WIN_ICO_00", // [228]
  "", // [229]
  "WIN_ICO_CLEAR", // [230]
  "", // [231]
  "", // [232]
  "WIN_OEM_RESET", // [233]
  "WIN_OEM_JUMP", // [234]
  "WIN_OEM_PA1", // [235]
  "WIN_OEM_PA2", // [236]
  "WIN_OEM_PA3", // [237]
  "WIN_OEM_WSCTRL", // [238]
  "WIN_OEM_CUSEL", // [239]
  "WIN_OEM_ATTN", // [240]
  "WIN_OEM_FINISH", // [241]
  "WIN_OEM_COPY", // [242]
  "WIN_OEM_AUTO", // [243]
  "WIN_OEM_ENLW", // [244]
  "WIN_OEM_BACKTAB", // [245]
  "ATTN", // [246]
  "CRSEL", // [247]
  "EXSEL", // [248]
  "EREOF", // [249]
  "PLAY", // [250]
  "ZOOM", // [251]
  "", // [252]
  "PA1", // [253]
  "WIN_OEM_CLEAR", // [254]
  "" // [255]
];

注意:上述数组中每个值的位置都很重要。空白处的 `""` 是未知值代码的占位符。
尝试使用这种静态数组查找方法来执行以下代码片段...

var keyCodes = [];

$("#reset").click(function() {
  keyCodes = [];
  $("#in").val("");
  $("#key-codes").html("var keyCodes = [ ];");
  $("#key-names").html("var keyNames = [ ];");
});

$(document).keydown(function(e) {
  keyCodes.push(e.which);
  updateOutput();
});

function updateOutput() {
  var kC = "var keyCodes = [ ";
  var kN = "var keyNames = [ ";

  var len = keyCodes.length;

  for (var i = 0; i < len; i++) {
    kC += keyCodes[i];
    kN += "'"+keyboardMap[keyCodes[i]]+"'";
    if (i !== (len - 1)) {
      kC += ", ";
      kN += ", ";
    }
  }

  kC += " ];";
  kN += " ];";

  $("#key-codes").html(kC);
  $("#key-names").html(kN);
}



var keyboardMap = [
  "", // [0]
  "", // [1]
  "", // [2]
  "CANCEL", // [3]
  "", // [4]
  "", // [5]
  "HELP", // [6]
  "", // [7]
  "BACK_SPACE", // [8]
  "TAB", // [9]
  "", // [10]
  "", // [11]
  "CLEAR", // [12]
  "ENTER", // [13]
  "ENTER_SPECIAL", // [14]
  "", // [15]
  "SHIFT", // [16]
  "CONTROL", // [17]
  "ALT", // [18]
  "PAUSE", // [19]
  "CAPS_LOCK", // [20]
  "KANA", // [21]
  "EISU", // [22]
  "JUNJA", // [23]
  "FINAL", // [24]
  "HANJA", // [25]
  "", // [26]
  "ESCAPE", // [27]
  "CONVERT", // [28]
  "NONCONVERT", // [29]
  "ACCEPT", // [30]
  "MODECHANGE", // [31]
  "SPACE", // [32]
  "PAGE_UP", // [33]
  "PAGE_DOWN", // [34]
  "END", // [35]
  "HOME", // [36]
  "LEFT", // [37]
  "UP", // [38]
  "RIGHT", // [39]
  "DOWN", // [40]
  "SELECT", // [41]
  "PRINT", // [42]
  "EXECUTE", // [43]
  "PRINTSCREEN", // [44]
  "INSERT", // [45]
  "DELETE", // [46]
  "", // [47]
  "0", // [48]
  "1", // [49]
  "2", // [50]
  "3", // [51]
  "4", // [52]
  "5", // [53]
  "6", // [54]
  "7", // [55]
  "8", // [56]
  "9", // [57]
  "COLON", // [58]
  "SEMICOLON", // [59]
  "LESS_THAN", // [60]
  "EQUALS", // [61]
  "GREATER_THAN", // [62]
  "QUESTION_MARK", // [63]
  "AT", // [64]
  "A", // [65]
  "B", // [66]
  "C", // [67]
  "D", // [68]
  "E", // [69]
  "F", // [70]
  "G", // [71]
  "H", // [72]
  "I", // [73]
  "J", // [74]
  "K", // [75]
  "L", // [76]
  "M", // [77]
  "N", // [78]
  "O", // [79]
  "P", // [80]
  "Q", // [81]
  "R", // [82]
  "S", // [83]
  "T", // [84]
  "U", // [85]
  "V", // [86]
  "W", // [87]
  "X", // [88]
  "Y", // [89]
  "Z", // [90]
  "OS_KEY", // [91] Windows Key (Windows) or Command Key (Mac)
  "", // [92]
  "CONTEXT_MENU", // [93]
  "", // [94]
  "SLEEP", // [95]
  "NUMPAD0", // [96]
  "NUMPAD1", // [97]
  "NUMPAD2", // [98]
  "NUMPAD3", // [99]
  "NUMPAD4", // [100]
  "NUMPAD5", // [101]
  "NUMPAD6", // [102]
  "NUMPAD7", // [103]
  "NUMPAD8", // [104]
  "NUMPAD9", // [105]
  "MULTIPLY", // [106]
  "ADD", // [107]
  "SEPARATOR", // [108]
  "SUBTRACT", // [109]
  "DECIMAL", // [110]
  "DIVIDE", // [111]
  "F1", // [112]
  "F2", // [113]
  "F3", // [114]
  "F4", // [115]
  "F5", // [116]
  "F6", // [117]
  "F7", // [118]
  "F8", // [119]
  "F9", // [120]
  "F10", // [121]
  "F11", // [122]
  "F12", // [123]
  "F13", // [124]
  "F14", // [125]
  "F15", // [126]
  "F16", // [127]
  "F17", // [128]
  "F18", // [129]
  "F19", // [130]
  "F20", // [131]
  "F21", // [132]
  "F22", // [133]
  "F23", // [134]
  "F24", // [135]
  "", // [136]
  "", // [137]
  "", // [138]
  "", // [139]
  "", // [140]
  "", // [141]
  "", // [142]
  "", // [143]
  "NUM_LOCK", // [144]
  "SCROLL_LOCK", // [145]
  "WIN_OEM_FJ_JISHO", // [146]
  "WIN_OEM_FJ_MASSHOU", // [147]
  "WIN_OEM_FJ_TOUROKU", // [148]
  "WIN_OEM_FJ_LOYA", // [149]
  "WIN_OEM_FJ_ROYA", // [150]
  "", // [151]
  "", // [152]
  "", // [153]
  "", // [154]
  "", // [155]
  "", // [156]
  "", // [157]
  "", // [158]
  "", // [159]
  "CIRCUMFLEX", // [160]
  "EXCLAMATION", // [161]
  "DOUBLE_QUOTE", // [162]
  "HASH", // [163]
  "DOLLAR", // [164]
  "PERCENT", // [165]
  "AMPERSAND", // [166]
  "UNDERSCORE", // [167]
  "OPEN_PAREN", // [168]
  "CLOSE_PAREN", // [169]
  "ASTERISK", // [170]
  "PLUS", // [171]
  "PIPE", // [172]
  "HYPHEN_MINUS", // [173]
  "OPEN_CURLY_BRACKET", // [174]
  "CLOSE_CURLY_BRACKET", // [175]
  "TILDE", // [176]
  "", // [177]
  "", // [178]
  "", // [179]
  "", // [180]
  "VOLUME_MUTE", // [181]
  "VOLUME_DOWN", // [182]
  "VOLUME_UP", // [183]
  "", // [184]
  "", // [185]
  "SEMICOLON", // [186]
  "EQUALS", // [187]
  "COMMA", // [188]
  "MINUS", // [189]
  "PERIOD", // [190]
  "SLASH", // [191]
  "BACK_QUOTE", // [192]
  "", // [193]
  "", // [194]
  "", // [195]
  "", // [196]
  "", // [197]
  "", // [198]
  "", // [199]
  "", // [200]
  "", // [201]
  "", // [202]
  "", // [203]
  "", // [204]
  "", // [205]
  "", // [206]
  "", // [207]
  "", // [208]
  "", // [209]
  "", // [210]
  "", // [211]
  "", // [212]
  "", // [213]
  "", // [214]
  "", // [215]
  "", // [216]
  "", // [217]
  "", // [218]
  "OPEN_BRACKET", // [219]
  "BACK_SLASH", // [220]
  "CLOSE_BRACKET", // [221]
  "QUOTE", // [222]
  "", // [223]
  "META", // [224]
  "ALTGR", // [225]
  "", // [226]
  "WIN_ICO_HELP", // [227]
  "WIN_ICO_00", // [228]
  "", // [229]
  "WIN_ICO_CLEAR", // [230]
  "", // [231]
  "", // [232]
  "WIN_OEM_RESET", // [233]
  "WIN_OEM_JUMP", // [234]
  "WIN_OEM_PA1", // [235]
  "WIN_OEM_PA2", // [236]
  "WIN_OEM_PA3", // [237]
  "WIN_OEM_WSCTRL", // [238]
  "WIN_OEM_CUSEL", // [239]
  "WIN_OEM_ATTN", // [240]
  "WIN_OEM_FINISH", // [241]
  "WIN_OEM_COPY", // [242]
  "WIN_OEM_AUTO", // [243]
  "WIN_OEM_ENLW", // [244]
  "WIN_OEM_BACKTAB", // [245]
  "ATTN", // [246]
  "CRSEL", // [247]
  "EXSEL", // [248]
  "EREOF", // [249]
  "PLAY", // [250]
  "ZOOM", // [251]
  "", // [252]
  "PA1", // [253]
  "WIN_OEM_CLEAR", // [254]
  "" // [255]
];
#key-codes,
#key-names {
  font-family: courier, serif;
  font-size: 1.2em;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="in" placeholder="Type here..." />
<button id="reset">Reset</button>
<br/>
<br/>
<div id="key-codes">var keyCodes = [ ];</div>
<div id="key-names">var keyNames = [ ];</div>


值得注意的键码

字母 A-Z:(65-90)

keyboardMap[65];  // A
...
keyboardMap[90];  // Z

数字 0-9:(48-57)

keyboardMap[48];  // 0
...
keyboardMap[57];  // 9

数字键盘 0-9:(96-105)

keyboardMap[96];   // NUMPAD0
...
keyboardMap[105];  // NUMPAD9

箭头键:(37-40)

keyboardMap[37];  // LEFT
keyboardMap[38];  // UP
keyboardMap[39];  // RIGHT
keyboardMap[40];  // DOWN

Tab键:(9)

keyboardMap[9];  // TAB

输入键:(13)

keyboardMap[13];  // ENTER

空格键:(32)

keyboardMap[32];  // SPACE

操作系统特定按键(91)Windows键(Windows)或命令键(Mac)

keyboardMap[91];  // OS_KEY

Alt键:(18)

keyboardMap[18];  // ALT

控制键:(17)

keyboardMap[17];  // CONTROL

Shift键:(16)

keyboardMap[16];  // SHIFT

大写锁定键:(20)

keyboardMap[20];  // CAPS_LOCK

无法处理特殊字符,如果使用Shift键输入按键,有什么解决方案吗? - Shaik Matheen

19

重要提示:上面接受的答案对于keyCode >= 144,即句点、逗号、破折号等无法正常工作。对于这些情况,您应该使用更通用的算法:

let chrCode = keyCode - 48 * Math.floor(keyCode / 48);
let chr = String.fromCharCode((96 <= keyCode) ? chrCode: keyCode);

如果你好奇为什么要这样做,这显然是因为内置JS函数String.fromCharCode()的行为。 对于keyCode <= 96的值,它似乎使用以下函数进行映射:

chrCode = keyCode - 48 * Math.floor(keyCode / 48)

对于keyCode > 96的值,它似乎使用以下函数进行映射:

chrCode = keyCode

如果这看起来像奇怪的行为,那么我同意。 不幸的是,这距离我在JS核心中看到的最奇怪的事情还有很长的路要走。

document.onkeydown = function(e) {
    let keyCode = e.keyCode;
    let chrCode = keyCode - 48 * Math.floor(keyCode / 48);
    let chr = String.fromCharCode((96 <= keyCode) ? chrCode: keyCode);
    console.log(chr);
};
<input type="text" placeholder="Focus and Type"/>


1
你在回答2009年的问题时使用let会让人感到困惑。 :-) - David Murdoch
14
如果有人通过查找“let”这个关键词来发现ES6的话,那我就帮了他们个忙;-) - galarant
@IzharAazmi 添加了解释。希望能有所帮助! - galarant
@DavidMurdoch 但现在已经不是2009年了 :) - mkoryak
1
它也不能正确地处理数字键盘上的数字键(扩展键盘右侧的键格)。 - Scott Buchanan
显示剩余2条评论

2
我猜这是为了游戏或快速响应的应用程序,因此使用了KEYDOWN而不是KEYPRESS。
编辑: 该死!我被纠正了(谢谢Crescent Fresh和David):JQuery(甚至底层的DOM主机)并没有公开WM_KEYDOWN和其他事件的详细信息。相反,它们预先消化了这些数据,并且在JQuery中,即使是keyDown事件,我们也会得到:
- event.keyCode 用于非字符键 - event.charCode 用于字符键
请注意,这些属性是Unicode值。 请注意,我无法在JQuery文档中找到对此的权威参考,但是网络上许多声誉良好的示例都引用了这两个属性。
因此,从我的一些Java(而不是JavaScript)中适应的以下代码完全错误...
以下代码将为您提供关键码的“有趣”部分:
  value = e.KeyCode;
  repeatCount = value & 0xFF;
  scanCode = (value >> 16) & 0xFF;  // note we take the "extended bit" deal w/ it later.
  wasDown = ((value & 0x4000) != 0);  // indicate key was readily down (auto-repeat)
  if (scanCode > 127)
      // deal with extended
  else
      // "regular" character

嗯,不行,scanCode 总是返回 0。而且 e.KeyCode 应该是 e.keyCode(KeyCode 未定义)。 - David Murdoch
嘿现在...你好,等等...什么?我们在谈论JScript还是什么? - Crescent Fresh
@David M. 对不起,也许JQuery会为我们“预处理”这些代码部分。我现在正在研究它。 - mjv
1
@mjv:你从哪里得到这段代码?它以前对你有用过吗?据我所知,没有DOM实现将所有信息编码为事件对象(无论是 keydown 还是其他事件)。 - Crescent Fresh
@Crescent:我从我的一些旧的Java代码中快速而天真地进行了适应。无论如何,你是完全正确的:即使对于键盘,DOM主机也不会提供任何这样的原始事件。我已经相应地修复了我的文本;仍在寻找来自JQuery.com的权威文档。 - mjv

2
你还可以使用只读属性key,它也支持像Shift等特殊键,并且受IE9的支持。
当按下非打印或特殊字符时,该值将是定义的键值之一,例如'Shift''Multiply'
  • 键盘事件 event.key
  • X             -> 'x'
  • Shift+X -> 'X'
  • F5            -> 'F5'

0

我最近编写了一个名为keysight的模块,它可以将keypresskeydownkeyup事件分别转换为字符和键。

例如:

 element.addEventListener("keydown", function(event) {
    var character = keysight(event).char
 })

它是否支持像ñ这样的键? - Arnold Roa
@ArnoldRoa,我刚刚推送了一些东西,希望能够支持那样的字符。我没有带重音字符的键盘,所以你介意测试一下吗? - B T

0

我知道这是一个老问题,但今天在寻找预打包解决方案时遇到了它,并没有找到真正满足我的需求的东西。

这里有一个解决方案(仅限英语),可以正确支持大写(shifted)、小写、标点符号、数字键盘等。

它还允许简单明了地识别和反应非可打印键,如ESC、箭头、功能键等。

https://jsfiddle.net/5hhu896g/1/

keyboardCharMap and keyboardNameMap are the key to making this work

感谢DaveAlger提供了命名键数组,这让我省去了很多打字和探索的时间!

你的代码非常优秀!感谢分享。它运行得非常好。我正在使用它来实现一个类似 Sublime 的多光标编辑,用于具有相同值的表单字段的项目。 - Todd Hammer

0

对于那些像我一样寻找键码的实际Unicode字符值的人,这里有一个函数。例如,给定右箭头Unicode键码,它将输出可见字符串\u001B\u005B\u0043

function toUnicode(theString) {
    var unicodeString = '';
    for (var i = 0; i < theString.length; i++) {
        var theUnicode = theString.charCodeAt(i).toString(16).toUpperCase();
        while (theUnicode.length < 4) {
            theUnicode = '0' + theUnicode;
        }
        theUnicode = '\\u' + theUnicode;
        unicodeString += theUnicode;
    }
    return unicodeString;
}

-2

1
这是不正确的!因为它没有考虑到用户键盘上当前启用的语言。例如,我输入'ф',但它给出'a'... - Vadim Guzev
抱歉,这是不正确的,文本将根据键盘布局进行更改。 - Arnold Roa

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接