KeyboardEvent.keyCode obsoleto. O que isso significa na prática?

92

De acordo com o MDN, definitivamente não devemos usar a .keyCodepropriedade. Está obsoleto:

https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

Na escola W3, esse fato é minimizado e há apenas uma nota lateral dizendo que .keyCodeé fornecido apenas para compatibilidade e que a versão mais recente da Especificação de eventos DOM recomenda o uso da .keypropriedade.

O problema é que .keynão há suporte para navegadores, então o que devemos usar? Tem algo que estou perdendo?

Jason210
fonte
3
.keyé compatível com todos os principais navegadores developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/…
Sinan Bolel

Respostas:

32

Você tem três maneiras de lidar com isso, conforme está escrito no link que você compartilhou.

if (event.key !== undefined) {

} else if (event.keyIdentifier !== undefined) {

} else if (event.keyCode !== undefined) {

}

você deve contemplá-los, esse é o caminho certo se você deseja suporte para vários navegadores.

Poderia ser mais fácil se você implementar algo assim.

var dispatchForCode = function(event, callback) {
  var code;

  if (event.key !== undefined) {
    code = event.key;
  } else if (event.keyIdentifier !== undefined) {
    code = event.keyIdentifier;
  } else if (event.keyCode !== undefined) {
    code = event.keyCode;
  }

  callback(code);
};
Miguel Lattuada
fonte
13
Eu li isso, mas parecia ser muito código extra por nenhuma outra razão além do MDN ter dito que algo está obsoleto, quando na verdade funciona bem em todos os principais navegadores. Mas se essa for a maneira correta, obrigado!
Jason210
3
Uau, olha isso. caniuse.com/#search=keyCode (Esta propriedade KeyboardEvent é efetivamente compatível com todos os navegadores (desde IE6 +, Firefox 2+, Chrome 1+ etc "falando sobre .keyCode)
Miguel Lattuada
2
Isso é o que é tão irritante em tudo isso. Todos os principais navegadores suportam keyCode, mas tente fazer uma verificação para a propriedade .key, que é a recomendada, e quase ninguém a usa!
Jason210
4
Sim, estamos até o final de maio de 2016 e o ​​Chrome finalmente implementou a propriedade KeyboardEvent.key. O Safari, juntamente com todos os navegadores móveis, ainda não se juntou ao grupo de "16,5% de todos os usuários". Além disso, infelizmente, o Microsoft Edge e o Gecko codificam alguns dos eventos de forma diferente, por exemplo: o evento chave para a seta para cima é codificado como "Up" em vez de "ArrowUp".
Joshua Dawson
Acho que isso ajudará você a stackoverflow.com/questions/41465542/…
Maven97
26

Além disso, todos os keyCode , which , charCode e keyIdentifier estão obsoletos:
charCodee keyIdentifiersão recursos não padrão.
keyIdentifieré removido a partir do Chrome 54 e o Opera 41.0
keyCoderetorna 0, no evento de pressionamento de tecla com caracteres normais no FF.

A propriedade principal :

 readonly attribute DOMString key

Contém um valor de atributo de chave correspondente à tecla pressionada

No momento em que este livro foi escrito, a keypropriedade era suportada por todos os principais navegadores a partir de: Firefox 52, Chrome 55, Safari 10.1, Opera 46. Exceto o Internet Explorer 11 que tem: identificadores de chave não padrão e comportamento incorreto com AltGraph. Mais informações
Se isso for importante e / ou a compatibilidade com versões anteriores for, você pode usar a detecção de recurso como no seguinte código:

Observe que o keyvalor é diferente de keyCodeou whichpropriedades porque: ele contém o nome da chave, não seu código. Se o seu programa precisa de códigos de caracteres, você pode fazer uso de charCodeAt(). Para caracteres únicos imprimíveis, você pode usar charCodeAt(), se estiver lidando com chaves cujos valores contenham vários caracteres, como as ArrowUp chances são: você está testando chaves especiais e executa as ações de acordo. Então, tentar implementar uma tabela de valores chaves e seus códigos correspondentes charCodeArr["ArrowUp"]=38, charCodeArr["Enter"]=13, charCodeArr[Escape]=27... e assim por diante, por favor dê uma olhada em valores-chave e seus códigos correspondentes

if(e.key!=undefined){
        var characterCode = charCodeArr[e.key] || e.key.charCodeAt(0);
    }else{
        /* As @Leonid suggeted   */
        var characterCode = e.which || e.charCode || e.keyCode || 0;
    }
        /* ... code making use of characterCode variable  */  

Pode ser que você queira considerar a compatibilidade com versões futuras, ou seja, usar as propriedades legadas enquanto estão disponíveis e apenas quando for descartado, mude para as novas:

if(e.which || e.charCode || e.keyCode ){
        var characterCode = e.which || e.charCode || e.keyCode;
    }else if (e.key!=undefined){
        var characterCode = charCodeArr[e.key] || e.key.charCodeAt(0);
    }else{
        var characterCode = 0;
    }

Veja também: a documentação da KeyboardEvent.codepropriedade e mais alguns detalhes nesta resposta .

user10089632
fonte
Sua solução não funciona no meu navegador (Windows 10, Chrome 60, teclado belga). Em primeiro lugar, a charCodeArrfunção não existe. Além disso, charCodeAtnão funciona para todos os valores de e.key. Por exemplo, para a chave Enter/ Return, o valor da e.keypropriedade é "Enter", e a execução charCodeArrdessa string retorna o valor 69(que é o código ASCII do caractere E).
John Slegers
@JohnSlegers, sim, isso foi um erro de digitação, eu quis dizer um array construído pelo usuário. Por favor, veja minha resposta atualizada para mais detalhes.
user10089632
19

TLDR: Eu sugiro que você deve usar o novo event.keye event.codepropriedades em vez dos legados. O IE e o Edge oferecem suporte a essas propriedades, mas ainda não oferecem suporte aos novos nomes de chave. Para eles, há um pequeno polyfill que os torna a saída dos nomes de chave / código padrão:

https://github.com/shvaikalesh/shim-keyboard-event-key


Eu vim para esta pergunta procurando o motivo do mesmo aviso MDN como OP. Depois de pesquisar mais um pouco, o problema com keyCodese torna mais claro:

O problema do uso keyCodeé que os teclados que não são em inglês podem produzir saídas diferentes e até mesmo teclados com layouts diferentes podem produzir resultados inconsistentes. Além disso, houve o caso de

Se você leu as especificações W3C: https://www.w3.org/TR/uievents/#interface-keyboardevent

Na prática, keyCode e charCode são inconsistentes entre plataformas e até mesmo a mesma implementação em sistemas operacionais diferentes ou usando localizações diferentes.

Ele descreve em profundidade o que havia de errado com keyCode : https://www.w3.org/TR/uievents/#legacy-key-attributes

Esses recursos nunca foram especificados formalmente e as implementações atuais do navegador variam de maneiras significativas. A grande quantidade de conteúdo legado, incluindo bibliotecas de script, que depende da detecção do agente do usuário e da ação adequada significa que qualquer tentativa de formalizar esses atributos e eventos legados corre o risco de interromper tanto conteúdo quanto consertaria ou habilitaria. Além disso, esses atributos não são adequados para uso internacional, nem abordam questões de acessibilidade.

Então, depois de estabelecer o motivo pelo qual o keyCode legado foi substituído, vamos ver o que você precisa fazer hoje:

  1. Todos os navegadores modernos oferecem suporte às novas propriedades ( keye code).
  2. O IE e o Edge oferecem suporte a uma versão mais antiga da especificação, que possui nomes diferentes para algumas chaves. Você pode usar um calço para isso: https://github.com/shvaikalesh/shim-keyboard-event-key (ou enrole seu próprio - é bem pequeno de qualquer maneira)
  3. O Edge corrigiu esse bug na versão mais recente (provavelmente será lançado em abril de 2018) - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/8860571/
  4. Consulte a lista de chaves de eventos que você pode usar: https://www.w3.org/TR/uievents-key/
Kumarharsh
fonte
De acordo com o MDN , nem o Internet Explorer nem o Edge suportamKeyboardEvent.code. Além disso, os valores parakeyecodedependem do navegador. Ambos os problemas tornamkeyecodenão são práticos para uso em aplicações da vida real.
John Slegers de
Se eu quiser testar as teclas de seta, page up / down, home & end, devo usar keyou code? Geralmente é uma chave física, mas pode depender do Num Lock e do layout também ... Qual é a prática recomendada?
Jake
12

O MDN já forneceu uma solução:

https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode

window.addEventListener("keydown", function (event) {
  if (event.defaultPrevented) {
    return; // Should do nothing if the default action has been cancelled
  }

  var handled = false;
  if (event.key !== undefined) {
    // Handle the event with KeyboardEvent.key and set handled true.
  } else if (event.keyIdentifier !== undefined) {
    // Handle the event with KeyboardEvent.keyIdentifier and set handled true.
  } else if (event.keyCode !== undefined) {
    // Handle the event with KeyboardEvent.keyCode and set handled true.
  }

  if (handled) {
    // Suppress "double action" if event handled
    event.preventDefault();
  }
}, true);
Vicky Gonsalves
fonte
3
Infelizmente, keyé um valor de string específico do navegador como "Enter"ou "ArrowUp"e não há uma maneira padronizada de convertê-lo no código correspondente. então você vai precisar de ainda mais código clichê para converter entre chave e código.
John Slegers
6

Por exemplo, se você deseja detectar se a tecla "Enter" foi clicada ou não:

Ao invés de

event.keyCode === 13

Faça como

event.key === 'Enter'
Thomas Gotwig
fonte