onKeyPress vs. onKeyUp e onKeyDown

329

Qual é a diferença entre esses três eventos? Ao pesquisar no Google, descobri que:

  • O onKeyDownevento é acionado quando o usuário pressiona uma tecla.
  • O onKeyUpevento é acionado quando o usuário libera uma chave.
  • O onKeyPressevento é acionado quando o usuário pressiona e libera uma tecla ( onKeyDownseguida por onKeyUp).

Eu entendo os dois primeiros, mas não é onKeyPresso mesmo que onKeyUp? É possível soltar uma tecla ( onKeyUp) sem pressioná-la ( onKeyDown)?

Isso é um pouco confuso, alguém pode esclarecer isso para mim?

instantsetsuna
fonte
3
Descobri que, se eu mantiver pressionada a tecla TAB, ela alterna continuamente entre todos os campos e aciona apenas 'onkeydown'.
nu everest
23
evento de pressionamento de tecla representa um caractere sendo digitado que pode ser usado para entrada, como 'a', 'D', '£', '©' e assim por diante. Por outro lado, os eventos keydown e keyup representam QUALQUER tecla sendo digitada, incluindo itens como backspace, tab, up, down, home, end e assim por diante.
Skinc7 # 4/16
2
"(ou é possível liberar uma tecla (KeyUp) sem pressionar (KeyDown)?)" - Sim. Por exemplo, a tecla tab: o evento keyup não pode ser capturado pelo mesmo elemento que o keydown.
Self Evident

Respostas:

191

Verifique aqui o link arquivado usado originalmente nesta resposta.

Nesse link:

Em teoria, os eventos onKeyDowne onKeyUprepresentam as teclas pressionadas ou liberadas, enquanto o onKeyPressevento representa um caractere sendo digitado. A implementação da teoria não é a mesma em todos os navegadores.

dcp
fonte
18
Monte um jsfiddle com base na postagem de @ Falk para demonstrar as idiossincrasias (usando o jquery): jsfiddle.net/zG9MF/2
fordareh:
Não consigo ver a página vinculada, mas o ponto sobre 'um caractere sendo digitado' é importante se você planeja usá-lo para qualquer tipo de validação. O evento de pressionamento de tecla não é acionado quando o usuário exclui um caractere, portanto sua validação não é acionada.
precisa saber é o seguinte
@ Tony Merryfield - link está funcionando bem para mim, eu apenas verifiquei novamente.
dcp
1
@ dcp - Sim, foi o suficiente para me colocar no caminho certo. Acabei de adicionar meu comentário para reforçar o ponto que o evento só dispara quando um personagem é digitado em oposição a qualquer keypress - você tem o meu upvote;)
Tony Merryfield
1
Além disso, em um "longo" pressionar de uma tecla, o evento KeyDown mantém a disparar até que a chave é liberada, caso em que KeyUp é acionado apenas uma vez;)
Bernoulli TI
195

KeyPress, KeyUpE KeyDownsão análogos aos, respectivamente: Click, MouseUp,e MouseDown.

  1. Down acontece primeiro
  2. Press acontece em segundo lugar (quando o texto é inserido)
  3. Up acontece por último (quando a entrada de texto estiver concluída).

A exceção é o webkit , que possui um evento extra:

keydown
keypress
textInput     
keyup

Abaixo está um trecho que você pode usar para ver quando os eventos são acionados:

window.addEventListener("keyup", log);
window.addEventListener("keypress", log);
window.addEventListener("keydown", log);

function log(event){
  console.log( event.type );
}

Robusto
fonte
1
Então, o KeyPress é apenas um evento extra que é o KeyDown e o TextInput? Como é que (KeyPress) é geralmente usado pelos desenvolvedores?
precisa
78
+1 melhor resposta - O * Para baixo acontece primeiro, o * Pressione acontece em segundo (quando o texto é inserido) e o * Para cima acontece por último (quando a entrada de texto é concluída).
Scott Pelak
2
-1 porque uma pequena experimentação no snippet contradiz sua analogia com o evento 'click'. O evento 'click' é acionado ao mesmo tempo que 'mouseup' (quando você solta o botão do mouse), mas o evento 'keypress' é acionado ao mesmo tempo que 'keydown' (quando a tecla é pressionada pela primeira vez).
Mark Amery
2
@ Robusto Na verdade, os eventos keypresse keydownrecebem literalmente o mesmo .timeStampvalor, que é preciso em intervalos de 5 microssegundos, mas esse não é realmente o meu ponto. O que clickquero dizer é que o evento não é acionado até você soltar o botão do mouse, por isso dizer que keypressé a versão do teclado clickfaz parecer que keypresstambém não será acionado até você soltar a tecla. De fato, esse não é o caso: ele dispara quando a tecla é pressionada, assim como keydownacontece. Portanto, keypressnão é de fato análogo a clickisso.
Mark Amery
2
@Robusto "como você explica que o 'pressionamento de tecla' sempre é gravado após o 'pressionamento de tecla'" - simples: a mesma ação do usuário (pressionar uma tecla) imediatamente aciona os dois manipuladores para serem empurrados para a fila de eventos, mas em uma ordem fixa . "você só quer ter um argumento por causa do argumento" - Eh? A tese central da sua resposta é que keypress, keyupe keydownsão análogos a click, mouseupe mousedown. A interpretação natural disso, para mim, é que keypressdispara no mesmo instante que keyup(assim como clicke mouseup). Como assim , senão isso?
Mark Amery
23

A maioria das respostas aqui está focada mais na teoria do que em questões práticas e há algumas grandes diferenças entre keyupe keypressno que diz respeito aos valores de campo de entrada, pelo menos no Firefox (testado em 43).

Se o usuário digitar 1um elemento de entrada vazio:

  1. O valor do elemento de entrada será uma sequência vazia (valor antigo) dentro do keypressmanipulador

  2. O valor do elemento de entrada será 1(novo valor) dentro do keyupmanipulador.

Isso é de importância crítica se você estiver fazendo algo que depende de conhecer o novo valor após a entrada e não o valor atual, como validação em linha ou tabulação automática.

Cenário:

  1. O usuário digita 12345em um elemento de entrada.
  2. O usuário seleciona o texto 12345.
  3. O usuário digita a letra A.

Quando o keypressevento é acionado após a inserção da letra A, a caixa de texto agora contém apenas a letra A.

Mas:

  1. Field.val () é 12345.
  2. $ Field.val (). Length é 5
  3. A seleção do usuário é uma sequência vazia (impedindo que você determine o que foi excluído substituindo a seleção).

Assim, parece que o navegador (Firefox 43) apaga a seleção do usuário, em seguida, dispara o keypressevento, em seguida, atualiza o conteúdo campos, então incêndios keyup.

usuario
fonte
16

onkeydowné acionado quando a tecla é pressionada (como nos atalhos; por exemplo, em Ctrl+A, Ctrlé mantida 'pressionada'.

onkeyup é acionado quando a chave é liberada (incluindo chaves modificadoras / etc)

onkeypressé acionado como uma combinação de onkeydowne onkeyup, ou dependendo da repetição do teclado (quando onkeyupnão é acionado). (esse comportamento repetido é algo que eu não testei. Se você testar, adicione um comentário!)

textInput(somente kit da web) é acionado quando algum texto é inserido (por exemplo, Shift+Ainsere maiúsculas 'A', mas Ctrl+Aseleciona texto e não insere nenhuma entrada de texto. Nesse caso, todos os outros eventos são acionados)

arunjitsingh
fonte
1
Acabei de confirmar que, de fato, "onkeypress" é chamado repetidamente quando a tecla é pressionada e ocorre "repetição do teclado". No entanto, isso também é verdade para "onkeydown"! (que é inesperado, dado o nome)
Venryx
11

Primeiro, eles têm um significado diferente: eles disparam:

  • KeyDown - quando uma tecla foi pressionada
  • KeyUp - quando um botão pressionado foi liberado e depois que o valor da entrada / área de texto é atualizado (o único dentre estes)
  • KeyPress - entre eles e não significa que uma tecla foi pressionada e liberada (veja abaixo).

Segundo, algumas teclas acionam alguns desses eventos e outros não . Por exemplo,

  • Ignora KeyPress delete, setas, PgUp/ PgDn, home/ end, ctrl, alt, shiftetc, enquanto TeclaEmBaixo e TeclaEmCima não (ver detalhes sobre esca seguir);
  • quando você alterna a janela via alt+ tabno Windows, apenas o KeyDown é altacionado porque a troca de janelas ocorre antes de qualquer outro evento (e o KeyDown tabé impedido pelo sistema, suponho, pelo menos no Chrome 71).

Além disso, lembre-se de que event.keyCode(e event.which) geralmente têm o mesmo valor para KeyDown e KeyUp, mas um valor diferente para o KeyPress. Experimente o playground que eu criei. A propósito, notei uma peculiaridade: no Chrome, quando pressiono ctrl+ ae input/ / textareaestá vazio, o KeyPress é acionado com event.keyCode(e event.which) igual a 1! (quando a entrada não está vazia, não é acionada).

Finalmente, há algumas pragmáticas :

  • Para manipular as setas, você provavelmente precisará usar onKeyDown: se o usuário aguentar , o KeyDown é acionado várias vezes (enquanto o KeyUp é acionado apenas uma vez ao soltar o botão). Além disso, em alguns casos, você pode impedir facilmente a propagação do KeyDown, mas não pode (ou não pode facilmente) impedir a propagação do KeyUp (por exemplo, se você deseja enviar ao entrar sem adicionar nova linha ao campo de texto).
  • Surpreendentemente, quando você pressiona uma tecla, digamos textarea, o KeyPress e o KeyDown são acionados várias vezes (Chrome 71), eu usaria o KeyDown se precisar do evento que é acionado várias vezes e o KeyUp para liberação de chave única.
  • O KeyDown geralmente é melhor para jogos quando você precisa fornecer uma melhor capacidade de resposta às ações deles.
  • escgeralmente é processado via KeyDown: o KeyPress não dispara e o KeyUp se comporta de maneira diferente para inputs e textareas em diferentes navegadores (principalmente devido à perda de foco)
  • Se você deseja ajustar a altura de uma área de texto ao conteúdo, provavelmente não usará onKeyDown, mas sim onKeyPress ( PS ok, é melhor usar onChange nesse caso ).

Eu usei os três no meu projeto, mas infelizmente posso ter esquecido algumas das pragmáticas. (de notar: há também inpute changeeventos)

YakovL
fonte
Eu não tinha pensado em adicionar a nova linha ao conteúdo do campo, mas isso é realmente importante.
FKEinternet 12/12/18
10

Este artigo de Jan Wolter é a melhor peça que encontrei, você pode encontrar a cópia arquivada aqui se o link estiver inoperante.

Explica muito bem todos os principais eventos do navegador,

O keydown evento ocorre quando a tecla for pressionada, seguido imediatamente pelo evento keypress. Em seguida, o evento keyup é gerado quando a chave é liberada.

Para entender a diferença entre keydown e keypress , é útil distinguir entre caracteres e chaves . Uma tecla é um botão físico no teclado do computador. Um caractere é um símbolo digitado pressionando um botão. Em um teclado americano, pressionar a 4tecla enquanto mantém pressionada a Shifttecla normalmente produz um caractere "cifrão". Este não é necessariamente o caso em todos os teclados do mundo. Em teoria, os eventos keydown e keyup representam teclas pressionadas ou liberadas, enquanto o pressionamento de teclaO evento representa um caractere sendo digitado. Na prática, nem sempre é assim que é implementado.

Por um tempo, alguns navegadores dispararam um evento adicional, chamado textInput , imediatamente após pressionar a tecla . As versões anteriores do padrão DOM 3 pretendiam isso como uma substituição do evento de pressionamento de tecla , mas toda a noção foi posteriormente revogada. O Webkit deu suporte a isso entre as versões 525 e 533, e disseram-me que o IE o apoiava, mas nunca o detecte , possivelmente porque o Webkit exigia que ele fosse chamado de textInput enquanto o IE o chamava de textinput .

Há também um evento chamado input , suportado por todos os navegadores, que é acionado logo após uma alteração em uma área de texto ou campo de entrada. Normalmente, o pressionamento de tecla é acionado, o caractere digitado aparece na área de texto e a entrada é acionada. Na verdade, o evento de entrada não fornece nenhuma informação sobre qual chave foi digitada - você teria que inspecionar a caixa de texto para descobrir o que mudou - para não considerarmos realmente um evento de chave e não documentá-lo aqui . Embora tenha sido originalmente definido apenas para áreas de texto e caixas de entrada, acredito que haja algum movimento para generalizá-lo para disparar em outros tipos de objetos também.

Suraj Jain
fonte
Melhor resposta, então como você pode obter, digamos, o símbolo do cifrão ao pressionar a tecla?
bluejayke
10

Parece que onkeypress e onkeydown fazem o mesmo (com a pequena diferença de teclas de atalho já mencionadas acima).

Você pode tentar isso:

<textarea type="text" onkeypress="this.value=this.value + 'onkeypress '"></textarea>
<textarea type="text" onkeydown="this.value=this.value + 'onkeydown '" ></textarea>
<textarea type="text" onkeyup="this.value=this.value + 'onkeyup '" ></textarea>

E você verá que os eventos onkeypress e onkeydown são acionados enquanto a tecla é pressionada e não quando a tecla é pressionada.

A diferença é que o evento é disparado não uma vez, mas muitas vezes (desde que você mantenha a tecla pressionada). Esteja ciente disso e lide com eles de acordo.

Falk
fonte
Ctrl, Shift, CapsLock, Backspace e outras teclas que não digitam algo não causam umkeypress evento, mas sempre acionam a keydown.
CPHPython 13/09/19
8

O evento onkeypress funciona para todas as chaves, exceto ALT, CTRL, SHIFT, ESC em todos os navegadores, enquanto o evento onkeydown funciona para todas as chaves. Significa que o evento onkeydown captura todas as chaves.

Mohd Sadiq
fonte
keypress também ignora exclusão, setas, home / end, PgUp / PgDn, veja a minha resposta para mais detalhes (você pode querer atualizar sua resposta também)
YakovL
4

Só queria compartilhar uma curiosidade:

ao usar o evento onkeydown para ativar um método JS, o código para esse evento NÃO é o mesmo que você obtém com o onkeypress!

Por exemplo, as teclas do teclado numérico retornam os mesmos códigos de código que as teclas numéricas acima das teclas de letras ao usar a tecla onkeypress, mas NÃO ao usar a tecla onkeydown!

Demorei alguns segundos para descobrir por que meu script, que verificava determinados códigos, falhou ao usar onkeydown!

Demonstração: https://www.w3schools.com/code/tryit.asp?filename=FMMBXKZLP1MK

e sim. Eu sei que a definição dos métodos é diferente .. mas o que é muito confuso é que em ambos os métodos o resultado do evento é recuperado usando event.keyCode .. mas eles não retornam o mesmo valor .. não é muito implementação declarativa.

Baterista
fonte
Parece que as coisas são as mesmas para Numeric Character ( 0123456789)
Mrigank Pawagi
E você notou que keyDown dá a chave no teclado, enquanto keyPress dá o caráter exato que acabou de digitar (ou clicado)
Mrigank Pawagi
2

Basicamente, esses eventos agem de maneira diferente em diferentes tipos e versões de navegadores. Criei um pequeno teste jsBin e você pode verificar o console para descobrir como esses eventos se comportam no seu ambiente de destino, espero que ajude. http://jsbin.com/zipivadu/10/edit

Ken Chan
fonte
1

Resposta atualizada:

KeyDown

  • Dispara várias vezes quando você mantém as teclas pressionadas.
  • Meta chave de acionamento.

Pressione o botão

  • Dispara várias vezes quando você mantém as teclas pressionadas.
  • Será que não disparar chaves meta.

KeyUp

  • Dispara uma vez no final quando você solta a tecla.
  • Meta chave de acionamento.

Este é o comportamento em ambos addEventListenere jQuery.

https://jsbin.com/vebaholamu/1/edit?js,console,output <- tente exemplo

mostra exemplo com a manutenção do SSS

(a resposta foi editada com a resposta correta, captura de tela e exemplo)

Quang Van
fonte
Exceto para keydown que dispara várias vezes também
bluejayke
-1, porque pelo menos um detalhe está errado em pelo menos o Chrome; como @bluejayke diz, o KeyDown também é acionado repetidamente quando você pressiona uma tecla.
Mark Amery
Sim, vocês estão certos, desculpe pelo meu erro; resposta editada.
Quang Van
0

Alguns fatos práticos que podem ser úteis para decidir qual evento manipular (execute o script abaixo e foque na caixa de entrada):

$('input').on('keyup keydown keypress',e=>console.log(e.type, e.keyCode, e.which, e.key))
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input/>

Pressionando:

  • chaves não inserção / tipagem (por exemplo Shift, Ctrl) não irá desencadear uma keypress. Pressione Ctrle solte-o:

    keydown 17 17 Controle

    keyup 17 17 Controle

  • teclas de teclados que aplicam transformações de caracteres a outros caracteres podem levar a Dead e duplicar "teclas" (por exemplo ~, ´) ativadas keydown. Pressione ´e solte-o para exibir um duplo ´´:

    keydown 192 192 Dead

    keydown 192 192 ´´

    tecla 180 180 ´

    tecla 180 180 ´

    keyup 192 192 Dead

Além disso, as entradas sem digitação (por exemplo, à distância <input type="range">) ainda acionarão todos os eventos de digitação , pressionamento de tecla e pressionamento de tecla de acordo com as teclas pressionadas.

CPHPython
fonte