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

这就是我现在拥有的:

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

如果 e.keyCode可能不是 ASCII 字符(Altbackspacedelarrows等) ..。 我现在需要以某种方式(最好是以编程方式——而不是使用查找表)从 value中对这些值进行 trim

我在用 jQuery。

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

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

337840 次浏览

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

编辑 : 该死!我纠正一下(感谢新月和大卫) : 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

也许我没有正确理解这个问题,但是如果你想捕获两个输入,你可以不使用 keyup吗?

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

根据我的经验,String.fromCharCode(e.keyCode)是不可靠的。String.fromCharCode期望 Unicode 字符代码作为参数; e.keyCode返回 javascript 密钥代码。Javascript 键码和 unicode 字符码是 没有的同一个东西!特别是,数字键返回不同于普通数字键的 keycode(因为它们是不同的键) ,而对于 upperlowercase两个字母返回相同的 keycode(在这两种情况下你按了相同的键) ,尽管它们有不同的 charcodes

例如,普通数字键1生成 keycode49的事件,而数字键1(打开 Numlock)生成 keycode97。与 String.fromCharCode一起使用,我们得到以下结果:

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

String.fromCharCode需要的是 Unicode 字符码,而不是 javascript 密钥码。键 a生成一个 keycode为65的事件,与它将要生成的字符的大小写无关(在事件中,如果按下 Shift键等,还有一个修饰符)。字符 a的 Unicode charcode为61,而字符 keycode0的 charcode为41(例如,根据 keycode1)。然而,这些都是 hex值,转换为十进制后,我们得到的 charcode值为“ A”为65,“ a”为97。[1]这与我们从 String.fromCharCode得到的这些值是一致的。

我自己的要求仅限于处理数字和普通字母(接受或拒绝取决于字符串中的位置)和让控制字符(F-key,Ctrl-something)通过。因此,我可以检查控制字符,如果它不是一个控制字符,我检查一个范围,只有这样,我才需要得到实际的字符。鉴于我不担心大小写(我把所有的字母都改为大写) ,并且已经限制了键码的范围,我只需要担心数字键盘上的键。以下内容足以说明这一点:

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 十进制字符对于普通拉丁字母是重叠的。

请参考此链接 从按键获取键码和任何键码的字符值

$('input#inp').keyup(function(e){
$(this).val(String.fromCharCode(e.keyCode));
$('div#output').html('Keycode : ' + e.keyCode);
});

按键代码索引的可读键名

键代码相对较少,所以我只是列出了静态数组中所有对应的值,这样我就可以简单地使用 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 Key: (9)

keyboardMap[9];  // TAB

输入密钥: (13)

keyboardMap[13];  // ENTER

空格键: (32)

keyboardMap[32];  // SPACE

操作系统特定键 (91) < em > Windows 键(Windows)或命令键(Mac)

keyboardMap[91];  // OS_KEY

Alt Key: (18)

keyboardMap[18];  // ALT

控制键: (17)

keyboardMap[17];  // CONTROL

Shift 键: (16)

keyboardMap[16];  // SHIFT

大写锁键: (20)

keyboardMap[20];  // CAPS_LOCK

只需要注意一点: 上述已接受的答案对于 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"/>

我知道这是一个古老的问题,但我今天遇到它,寻找一个预先包装的解决方案,这个问题,并没有找到真正满足我的需要。

这里有一个解决方案(只有英语) ,正确支持大写(移位) ,小写,标点符号,数字键盘等。

它还允许简单直接地识别非打印键,如 ESC、 Arrows、 Function 键等。

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

keyboardCharMap and keyboardNameMap are the key to making this work

感谢 DaveAlger 通过提供命名密钥数组为我节省了一些输入-和许多发现。

我最近编写了一个名为 钥匙瞄准器的模块,它分别将 keypresskeydownkeyup事件转换为字符和键。

例如:

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

对于那些像我一样来这里寻找键码实际 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;
}

还可以使用只读属性 key。它还尊重特殊的键,如 shift等,并得到 IE9的支持。

当按下一个不可打印或特殊字符时,该值将位于定义的 键值上,如 'Shift''Multiply'

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