Obtenha o valor de caractere do KeyCode em JavaScript ... depois apare


152

Isto é o que eu tenho agora:

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

Se a e.keyCodenão ser um caractere ASCII ( Alt, backspace, del, arrows, etc.) ... Eu agora precisa trimdestes valores devalue de alguma forma (de preferência por meio de programação - não com tabelas de pesquisa).

Estou usando jQuery.

Eu devo usar o keydownevento. keyPressnão ativa para determinadas chaves eu preciso de captura ( Esc, del, backspace, etc.).

Não consigo usar setTimeoutpara obter o valor da entrada. setTimeout(function(){},0)é muito lento.


11
Você deve usar keydownpara capturar códigos de caracteres? Você está em uma viagem infernal: quirksmode.org/js/keys.html (dica: use keypress!! )
Crescent Fresh

1
O caso do personagem não importa. E eu preciso capturar para cima, baixo, esquerda, direita, esc, del, backspace por pelo menos FF e IE; então, pressionar as teclas está fora de questão. Obrigado pela dica embora. :-) #
55460 David Murdoch

Em resposta a esse problema, acabei de escrever um plug-in do jQuery: github.com/bpeacock/key-to-charCode Ele está um pouco sujo e pode ser melhor integrado ao jQuery, mas é um começo.
Brian Peacock

1
Para quem veio aqui tentando resolver o problema do KeyCode, mas realmente quer apenas ver qual tecla foi pressionada, confira esta resposta . TLDR:document.onkeydown = function(e){ console.log('Key: ' + e.key); }
user1717828

Respostas:


164

Talvez eu não tenha entendido a pergunta corretamente, mas você não pode usá- keyuplo se quiser capturar as duas entradas?

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

10
Isso não funciona com outros locais que estão fora do intervalo ASCII (como latin-1, por exemplo, alemão, francês, italiano e espanhol, se você precisar). Também falha em chaves não imprimíveis, obviamente.
Florian Bösch 29/01

9
Isso também falha ao usar números no teclado numérico, e.keyCode não é o código ASCII (ou mesmo UTF-x).
Tom Chiverton

2
Resposta ruim, nem funciona com caracteres básicos. O ponto-e-vírgula keyCode, por exemplo, é 186, execute um String.fromCharCode () nele e você obterá lixo. O problema é que keyCode não corresponde ao ASCII para todos os caracteres. O caractere ASCII para ponto e vírgula é 59. O mesmo problema ocorre com todos os caracteres especiais. KeyCode NÃO retorna o código correto para String.fromCharCode ().
Alexander Tsepkov 4/17

193

Na minha experiência String.fromCharCode(e.keyCode)não é confiável. String.fromCharCodeespera códigos de códigos unicode como argumento; e.keyCoderetorna códigos de chave javascript. Os códigos-chave Javascript e os códigos Unicode não são a mesma coisa! Em particular, as teclas do teclado numérico retornam um número diferente keycodedas teclas numéricas comuns (já que são teclas diferentes), enquanto o mesmo keycodeé retornado para ambas as letras uppere lowercaseletras (você pressionou a mesma tecla nos dois casos), apesar de terem teclas diferentes.charcodes .

Por exemplo, a tecla numérica comum 1 gera um evento com keycode49 enquanto a tecla numérica 1 (com ativado Numlock) gera keycode97. Usada com String.fromCharCode, obtemos o seguinte:

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

String.fromCharCodeespera códigos de código unicode, não códigos de chave javascript. A tecla agera um evento com um keycodede 65, independente do caso do caractere que geraria (também há um modificador para se a Shifttecla for pressionada, etc. no evento). O personagem atem um unicode charcodede 61 enquanto o personagem Atem um charcodede 41 (de acordo com, por exemplo, http://www.utf8-chartable.de/ ). No entanto, esses são hexvalores, a conversão para decimal nos dá umacharcode de 65 para "A" e 97 para "a". [1] Isso é consistente com o que obtemos String.fromCharCodedesses valores.

Meu próprio requisito era limitado ao processamento de números e letras comuns (aceitar ou rejeitar, dependendo da posição na string) e permitir que caracteres de controle ( Fteclas, Ctrlalgo) passassem . Assim, posso verificar os caracteres de controle, se não for um caractere de controle, verifico em relação a um intervalo e só então preciso obter o caractere real. Como não estou preocupado com maiúsculas e minúsculas (mudo todas as letras para maiúsculas de qualquer maneira) e já limitei o intervalo de códigos de teclas, só preciso me preocupar com as teclas do teclado numérico. O seguinte é suficiente para isso:

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

Em geral, uma função para retornar o caractere de forma confiável charcodeseria ótima (talvez como um plugin do jQuery), mas não tenho tempo para escrevê-lo agora. Desculpe.

Eu também mencionaria e.which(se você estiver usando jQuery) que normaliza e.keyCodee e.charCode, para que você não precise se preocupar com o tipo de tecla que foi pressionada. O problema de combiná-lo com String.fromCharCoderestos.

[1] Fiquei confuso por um tempo -. todos os documentos dizem que String.fromCharCodeespera um unicode charcode, enquanto, na prática, parecia funcionar para códigos ASCII, mas acho que devido à necessidade de converter em decimal de hexadecimal, combinado com o fato de que códigos de ASCII e códigos decimais unicode se sobrepõem a códigos comuns letras latinas.


2
Esse comentário acabou com todos os meus problemas. É incrível para mim que jQuery não tem implementado um "fromKeyCode" equivalente a "String.fromCharCode" do javascript
Chris J

27
Parece que o evento KeyPress faz isso. Consulte stackoverflow.com/a/9350415/209568 . Nos documentos do jQuery "Observe que keydown e keyup fornecem um código indicando qual tecla foi pressionada, enquanto a tecla pressionada indica qual caractere foi digitado. Por exemplo, um" a "minúsculo será relatado como 65 por keydown e keyup, mas como 97 por keypress Um "A" maiúsculo é relatado como 65 por todos os eventos. Devido a essa distinção, ao capturar pressionamentos de tecla especiais, como teclas de seta, .keydown () ou .keyup () é uma opção melhor. "
Adam

Isso é muito desagradável para aqueles de nós que são viciados em keydown.
Isaac Bolinger

Uma observação sobre esse último bit sobre ASCII e Unicode. Unicode possui todos os 128 caracteres ASCII no mesmo local. Isso foi intencional, para que qualquer arquivo originalmente codificado como ASCII possa se disfarçar como (e ser convertido em) Unicode sem nenhum trabalho necessário. Os caracteres ASCII estendidos não estão no mesmo lugar; portanto, se você os usou, não terá sorte.
DanielM

1
O objetivo keyCodeé saber qual tecla foi pressionada, não saber qual caractere usar. Por exemplo, "U" em um teclado Dvorak tem o mesmo código de tecla que "F" em um teclado QWERTY ou "ㄹ" em um teclado coreano etc. O objetivo não é convertê-lo em um caractere, ele está lá para que você possa mapeie facilmente as coisas para a posição do teclado.
Vincent McNabb

77

Nomes de chave legíveis indexados por código de chave

Existem relativamente poucos de códigos de tecla de modo que simplesmente mencionadas, todos os valores correspondentes de uma matriz estático para poderia simplesmente converter o número 65em AusokeyboardMap[65]

Nem todos os códigos de chave são mapeados para um caractere imprimível; portanto, outra string identificável é retornada.

Pode ser necessário modificar a matriz para atender às suas necessidades e pode simplesmente retornar cadeias vazias para todos os caracteres que você não deseja traduzir. A matriz a seguir permite determinar de maneira rápida e confiável qual tecla foi pressionada em qualquer ambiente. Aproveitar!

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

Nota: A posição de cada valor na matriz acima é importante. O ""são espaços reservados para códigos com valores desconhecidos.

Experimente o seguinte trecho de código usando esta abordagem de pesquisa de matriz estática ...


Códigos-chave dignos de nota

Letras AZ: (65-90)

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

Dígitos 0-9: (48-57)

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

Teclado numérico 0-9: (96-105)

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

Teclas de seta: (37-40)

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

Tecla Tab: (9)

keyboardMap[9];  // TAB

Tecla Enter: (13)

keyboardMap[13];  // ENTER

Tecla da barra de espaço: (32)

keyboardMap[32];  // SPACE

Chave específica do SO (91) Chave do Windows (Windows) ou Chave de comando (Mac)

keyboardMap[91];  // OS_KEY

Tecla Alt: (18)

keyboardMap[18];  // ALT

Chave de controle: (17)

keyboardMap[17];  // CONTROL

Tecla Shift: (16)

keyboardMap[16];  // SHIFT

Tecla Caps Lock: (20)

keyboardMap[20];  // CAPS_LOCK

não está funcionando para caracteres especiais, se inserir teclas com tecla shift, alguma solução?
Shaik Matheen

14

Apenas uma observação importante: a resposta aceita acima não funcionará corretamente para keyCode> = 144, ou seja, ponto, vírgula, traço etc. Para aqueles que você deve usar um algoritmo mais geral:

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

Se você está curioso sobre o porquê, isso é aparentemente necessário devido ao comportamento da função JS interna String.fromCharCode(). Para valores keyCode <= 96dele parece mapear usando a função:

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

Para valores keyCode > 96dele parece mapear usando a função:

chrCode = keyCode

Se isso parece um comportamento estranho, então bem ... eu concordo. Infelizmente, isso seria muito longe da coisa mais estranha que eu já vi no núcleo do 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
Você está indo para confundir as pessoas usando letem uma resposta a uma pergunta de 2009. :-)
David Murdoch

12
Se alguém descobrir ES6, observando-se let, em seguida, eu fiz-lhes um favor ;-)
galarant

@ galarant Você pode explicar por que / como isso funciona?
Izhar Aazmi

@IzharAazmi adicionou uma explicação. Espero que ajude!
galarant

1
Também não funciona corretamente para as teclas numéricas em um teclado numérico (a grade de teclas à direita dos teclados estendidos).
22718 Scott

2

Estou assumindo que isso é para um jogo ou para um tipo de aplicativo de resposta rápida, portanto, o uso de KEYDOWN que KEYPRESS.

Editar : Dang! Estou corrigido (obrigado Crescent Fresh e David): JQuery (ou melhor, os hosts DOM subjacentes) não expõem os detalhes do WM_KEYDOWN e de outros eventos. Em vez disso, eles pré-digerem esses dados e, no caso de keyDown, mesmo no JQuery, obtemos:

Observe que essas propriedades são os valores UniCode.
Observe que não consegui encontrar uma referência autoritativa a isso nos documentos do JQuery, mas muitos exemplos respeitáveis ​​na rede se referem a essas duas propriedades.

O código a seguir, adaptado de algum java (não javascript) meu, está totalmente errado ...

A seguir, serão apresentadas as partes "interessantes" do código-chave:

  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, sem necessidade, scanCode sempre resulta em 0. E e.KeyCode deve ser e.keyCode (KeyCode é indefinido).
David Murdoch

Ei agora ... Olá, espere ... o que ?? Estamos falando de JScript aqui ou algo assim?
Crescent Fresh

@ David M. Meu mau, talvez JQuery "pré-digere" essas partes do código para nós. Estou investigando agora.
Mjv

1
@mjv: onde você conseguiu esse código? Já trabalhou para você? A implementação do AFAIK no DOM codifica todas essas informações no objeto de evento ( keydownou não).
Crescent Fresh

@Crescent: adaptei-o de forma rápida e ingênua a partir de algum código java meu, muito antigo ... Enfim, você está totalmente certo: nenhum dos hosts do DOM distribui esses eventos brutos, mesmo para o teclado. Eu consertei minha prosa de acordo; ainda à procura de um doc oficial sobre o assunto a partir JQuery.com
mjv

0

Sei que essa é uma pergunta antiga, mas hoje me deparei com ela procurando uma solução pré-empacotada para esse problema e não encontrei nada que realmente atendesse às minhas necessidades.

Aqui está uma solução (somente em inglês) que suporta corretamente letras maiúsculas (deslocadas), letras minúsculas, pontuação, teclado numérico etc.

Também permite a identificação simples e direta - e a reação a - teclas não imprimíveis, como ESC, Arrows, teclas de função, etc.

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

keyboardCharMap and keyboardNameMap are the key to making this work

Agradeço ao DaveAlger por me poupar algumas digitações - e muitas descobertas! - fornecendo a matriz de chaves nomeadas.


Seu violino é excelente! Obrigado por compartilhar. Funciona excelentemente. Eu estou usando-o para implementar uma edição Sublime estilo multi-cursor para os campos do formulário com os itens com os mesmos valores
Todd Martelo

0

Eu escrevi recentemente um módulo chamado keysight que traduz keypress, keydowne keyupeventos em personagens e chaves respectivamente.

Exemplo:

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

suporta chaves como ñ?
Arnold Roa

@ ArnoldRoa Acabei de lançar algo que espero apoiar personagens como esse. Eu não tenho um teclado com caracteres acentuados, você se importaria de testar?
BT

0

Para aqueles que vieram aqui procurando os valores reais de caracteres Unicode para um código-chave, como eu fiz, aqui está uma função para isso. Por exemplo, dado o código de chave unicode da seta para a direita, isso produzirá a string visível\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

Você também pode usar a propriedade somente leitura key. Também respeita teclas especiais comoshift etc. e é suportado pelo IE9.

Quando um caractere não imprimível ou especial é pressionado, o valor estará ativado nos valores de tecla definidos como 'Shift'ou 'Multiply'.

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

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.