从JavaScript中的KeyCode获取字符值,然后修剪


152

这就是我现在所拥有的:

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

如果e.keyCode可能不是一个ASCII字符(Altbackspacedelarrows,,等)......我现在需要trim这些价值从value某种程度上(最好是编程-不查找表)。

我正在使用jQuery。

我必须使用该keydown事件。keyPress不会激活某些键,我需要捕捉(Escdelbackspace等)。

我不能setTimeout用来获取输入的值。setTimeout(function(){},0)太慢了。


11
您必须使用keydown捕获字符代码吗?您正要经历一场地狱:quirksmode.org/js/keys.html(提示:使用keypress!!
Crescent Fresh

1
角色的大小写无关紧要。而且我需要捕获至少FF和IE的上,下,左,右,esc,del,backspace;因此按键是不可能的。谢谢你的提示。:-)
David Murdoch,2009年

为了解决这个问题,我刚刚编写了一个jQuery插件:github.com/bpeacock/key-to-charCode这有点麻烦,可以更好地集成到jQuery中,但这只是一个开始。
Brian Peacock

1
对于来到这里尝试解决KeyCode问题但实际上只想查看按下了什么键的任何人,请查看此答案。TLDR:document.onkeydown = function(e){ console.log('Key: ' + e.key); }
user1717828

Answers:


164

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

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

10
不适用于ASCII范围以外的其他语言环境(例如,如果您必须知道,则例如latin-1,德语,法语,意大利语和西班牙语)。显然,对于不可打印的键也失败。
FlorianBösch2013年

9
当在数字键盘上使用数字时,这也将失败,例如e.keyCode不是ASCII(甚至是UTF-x)代码。
Tom Chiverton 2014年

2
错误的答案,它甚至不适用于基本字符。例如,分号keyCode是186,在其上运行String.fromCharCode(),您将得到垃圾。问题在于keyCode并非对于所有字符都对应于ASCII。分号的ASCII字符为59。每个特殊字符都存在相同的问题,keyCode不会为String.fromCharCode()返回正确的代码。
亚历山大·谢普科夫

193

以我的经验String.fromCharCode(e.keyCode)是不可靠的。 String.fromCharCode期望unicode charcodes作为参数;e.keyCode返回javascript密钥代码。Javascript键码和unicode字符码不是同一回事!特别是,数字键盘键返回的keycode数字与普通数字键不同(因为它们是不同的键),而字母和字母keycode都返回相同的数字(在两种情况下都按相同的键),尽管它们具有不同的。 upperlowercasecharcodes

例如,普通数字键1产生一个带有keycode49 的事件,而数字键盘键1(带有Numlockon)产生一个keycode97。与之配合使用,String.fromCharCode我们得到以下信息:

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

String.fromCharCode需要unicode字符代码,而不是javascript键代码。按键会a生成一个keycode65 的事件,而与要生成的字符的大小写无关(对于Shift按键是否按下等,还有一个修饰符,等等)。的字符a具有一个unicode charcode的61,而字符A具有charcode的41(根据,例如,http://www.utf8-chartable.de/)。但是,这些都是hex值,如果将其转换为小数charcode,则“ A” 的值为65,而“ a”的值为97。[1] 这与我们从String.fromCharCode这些值中得到的一致。

我自己的要求仅限于处理数字和普通字母(根据字符串中的位置接受还是拒绝)以及让控制字符(F-keys -something Ctrl)通过。因此,我可以检查控制字符,如果不是控制字符,则可以检查范围,然后才需要获取实际字符。鉴于我不担心大小写(无论如何我都将所有字母都更改为大写)并且已经限制了键码的范围,所以我只需要担心数字键盘的键。满足以下条件即可:

String.fromCharCode((96 <= key && key <= 105)? key-48 : key)

更一般而言,可靠地从中返回字符的功能charcode会很棒(也许作为jQuery插件),但是我现在没有时间编写它。抱歉。

我还要提到e.which(如果您使用的是jQuery)规范化e.keyCodee.charCode,这样您就不必担心按下了哪种键。与String.fromCharCode遗骸相结合的问题。

[1]我有些困惑- 所有文档都说String.fromCharCode期望使用unicode charcode,而实际上它似乎适用于ASCII字符代码,但是我认为这是由于需要从十六进制转换为十进制,再加上ASCII字符代码和unicode十进制字符代码与普通字符重叠的事实拉丁字母。


2
这句话几乎解决了我所有的问题。令我惊讶的是,jQuery没有实现与javascript的“ String.fromCharCode”等效的“ fromKeyCode”
Chris

27
看来KeyPress事件可以做到这一点。请参阅stackoverflow.com/a/9350415/209568。在jQuery docs中,“请注意keydown和keyup提供了一个代码,指示按下哪个键,而keypress指示输入了哪个字符。例如,小写的“ a”将被keydown和keyup报告为65,但被keypress报告为97所有事件均将大写字母“ A”报告为65。由于这种区别,在捕获特殊的击键(例如箭头键)时,.keydown()或.keyup()是更好的选择。
2012年

对于我们沉迷于按键的人来说,这是最不愉快的。
艾萨克·伯林格

关于ASCII和Unicode的最后一点的说明。Unicode在同一位置具有所有128个ASCII字符。这是有意的,因此任何原始编码为ASCII的文件都可以伪装成Unicode(并转换为Unicode)而无需做任何工作。不过,扩展的ASCII字符不在同一位置,因此,如果使用这些字符,您将很不走运。
DanielM

1
keyCode是要知道按下了哪个键,不知道是什么角色使用。例如,Dvorak键盘上的“ U”与QWERTY键盘上的“ F”或韩语键盘上的“ㄹ”具有相同的键代码。关键是不要将其转换为字符,因此可以将其转换为字符。轻松将内容映射到键盘位置。
Vincent McNabb '18

77

可读的键名由键代码索引

有那么我简单列在一个静态数组中的所有相应的值,这样我就可以数简单地转换相对较少的键码65A使用keyboardMap[65]

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

您可能需要修改数组以满足您的需要,并且可以简单地为所有不需要翻译的字符返回空字符串。以下数组使我可以快速而可靠地确定在任何环境中按下了哪个键。请享用!

// 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]
];

注意: 上面数组中每个值的位置很重要。""是具有未知值码的占位符。

使用此静态数组查找方法尝试以下代码片段...


值得注意的关键代码

字母AZ:(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)或Command键(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)'17年

14

只是一个重要的注意事项:如果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
您将通过let回答2009
David Murdoch

12
如果有人通过查找发现了ES6,let那么我帮了他们一个忙;-)
激动人心的

@galarant您能否解释一下为什么/如何工作?
Izhar Aazmi '16

@IzharAazmi添加了解释。希望能帮助到你!
激动人心的

1
对于数字小键盘上的数字键(扩展键盘右侧的键网格),它也无法正常工作。
Scott Buchanan

2

我假设这是用于游戏或快速响应类型的应用程序,因此使用KEYDOWN而不是KEYPRESS。

编辑:当!我的立场是正确的(感谢Crescent Fresh和David):JQuery(甚至是底层的DOM主机)不会公开WM_KEYDOWN和其他事件的详细信息。而是他们预先消化了这些数据,对于keyDown甚至在JQuery中,我们得到:

请注意,这些属性是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

hm,no go,scanCode始终为0。e.KeyCode应该为e.keyCode(未定义KeyCode)。
David Murdoch,2009年

嘿,现在...你好,等等... 我们在这里谈论JScript还是什么?
新月新鲜

@David M.我不好,也许JQuery为我们“预消化”了这些代码部分。我正在调查。
mjv

1
@mjv:您从哪里获得此代码?它对您有用吗?AFAIK no DOM实现不会将所有信息编码到事件对象中(keydown或不会)。
新月新鲜

@Crescent:我从我的Java代码中快速天真地修改了该代码,无论如何,您还是很正确的:没有DOM主机提供任何此类原始事件,甚至对于键盘也没有。我据此修好了散文。仍在从JQuery.com寻找有关该主题的权威文档
mjv

0

我知道这是一个老问题,但是今天我遇到了这个问题,正在寻找针对该问题的预包装解决方案,但没有发现任何真正满足我需要的东西。

这是一个正确支持大写(转移),小写,标点,数字小键盘等的解决方案(仅英语)。

它还允许简单,直接地识别非打印键,并对其做出反应,例如ESC,箭头,功能键等。

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

keyboardCharMap and keyboardNameMap are the key to making this work

感谢DaveAlger为我节省了一些打字工作-以及许多发现!-通过提供命名键数组。


你的小提琴是最棒的!感谢分享。它表现出色。我正在使用它为具有相同值的项目的表单字段实现Sublime样式的多光标编辑
Todd Hammer

0

我最近写了一个模块调用keysight是翻译keypresskeydownkeyup事件为字符和钥匙分别。

例:

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

它支持ñ等键吗?
阿诺德·罗阿

@ArnoldRoa我刚刚推送了一些希望可以支持类似字符的东西。我没有带重音符号的键盘,所以您介意进行测试吗?
BT

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

0

您也可以使用只读属性key。它还尊重IE等特殊键shift,并且受IE9支持。

当按下不可打印或特殊字符时,该值将位于已定义键值中,例如'Shift''Multiply'

  • 键盘     event.key
  • X             -> 'x'
  • Shift+ X ->'X'
  • F5            -> 'F5'

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.