Teclas de seta de ligação em JS / jQuery

418

Como faço para vincular uma função às teclas de seta esquerda e direita em Javascript e / ou jQuery? Eu olhei para o plugin js-hotkey para jQuery (envolve a função de ligação incorporada para adicionar um argumento para reconhecer chaves específicas), mas ele não parece suportar teclas de seta.

Alex S
fonte

Respostas:

541
document.onkeydown = function(e) {
    switch(e.which) {
        case 37: // left
        break;

        case 38: // up
        break;

        case 39: // right
        break;

        case 40: // down
        break;

        default: return; // exit this handler for other keys
    }
    e.preventDefault(); // prevent the default action (scroll / move caret)
};

Se você precisar oferecer suporte ao IE8, inicie o corpo da função como e = e || window.event; switch(e.which || e.keyCode) {.


(editar 2020)
Observe que KeyboardEvent.whichagora está obsoleto. Veja este exemplo usandoKeyboardEvent.key uma solução mais moderna para detectar teclas de seta.

Sygmoral
fonte
28
De longe a melhor resposta. Usos e.whichcomo o jQuery recomenda para o navegador cruzado, usa em e.preventDefault()vez de return false( return falseem um manipulador de eventos do jQuery aciona ambos e.preventDefault()e e.stopPropagation(), o segundo dos quais causará falha de eventos adicionados posteriormente, pois o evento não será propagado para eles), e no No final do comutador, retornará sem chamar e.preventDefault()se for qualquer outra tecla que não esteja sendo procurada para não atrapalhar o uso de outras teclas e, em vez disso, $.ui.keyCode.DOWNserá comparada aos números (MUITO mais rápido).
Jimbo Jonny
2
Nathan: parece que nem todos os códigos de teclas são consistentes entre os navegadores, mas as teclas de seta são algumas delas. Veja aqui: stackoverflow.com/questions/5603195/…
Sygmoral
1
@MichaelScheper - 1) variáveis! = Constantes, independentemente de serem ou não alteradas ... o mecanismo ainda precisa tratá-las como vars até que as constantes ES6 sejam onipresentes o suficiente para que o jQuery possa usar constantes 2) números realmente mágica quando há comentário bem ao lado deles dizendo exatamente o que eles são, e 3) ... continuação
Jimbo Jonny
2
... 3) ao acessar $.ui.keyCode.DOWNvocê procura $no seu escopo lexical, não o encontra, subindo um nível ... procurando $, repita até no escopo global, encontre no global window, acesse $na janela, acesse uina janela, acesse na window.$, acesse keyCodena window.$.ui, acesso DOWNem window.$.ui.keyCodechegar ao valor primitivo você quiser comparar, em seguida, fazer a sua real comparando. Se essa velocidade é importante ou não para você, é uma decisão pessoal, apenas tenho a tendência de evitar 4 níveis de acesso quando há uma situação em que posso escrever / comentar com facilidade o primitivo.
Jimbo Jonny
1
@NathanArthur Aqui eu encontrei duas boas ferramentas online para testar os códigos de tecla do teclado: keycode.info asquare.net/javascript/tests/KeyCode.html unixpapa.com/js/key.html
Riccardo Volpe
451
$(document).keydown(function(e){
    if (e.which == 37) { 
       alert("left pressed");
       return false;
    }
});

Códigos de caracteres:

37 - esquerda

38 - até

39 - direita

40 - abaixo

Josh
fonte
4
Existe algum objetivo para o retorno?
Alex S
19
Ele impede que outros eventos de keydown sejam atingidos.
S_hewitt 9/09/09
9
Sombra: não, ele quer dizer que ele pare o evento keydown de disparar em outros elementos DOM
JasonWoof
3
Exceto 39 também é apóstrofo, não é?
Paul D. Waite
25
Ao usar o jQuery, use em e.whichvez de e.keyCodeobter mais suporte ao navegador. Veja meu comentário abaixo.
Sygmoral
108

Você pode usar o keyCode das teclas de seta (37, 38, 39 e 40 para esquerda, cima, direita e baixo):

$('.selector').keydown(function (e) {
  var arrow = { left: 37, up: 38, right: 39, down: 40 };

  switch (e.which) {
    case arrow.left:
      //..
      break;
    case arrow.up:
      //..
      break;
    case arrow.right:
      //..
      break;
    case arrow.down:
      //..
      break;
  }
});

Veja o exemplo acima aqui .

CMS
fonte
1
Não tenho certeza do seu uso do || operador na linha 2. Um valor diferente de zero ou diferente de zero é específico e não é garantido? Eu usaria algo mais como: var keyCode = (e.keyCode? E.keyCode: e.which); +1 para o uso do objeto de seta para fornecer nomes legíveis aos casos.
Mnebuerquo #
6
Se você estiver usando jQuery, você não precisa de teste para e.which: The event.which property normalizes event.keyCode and event.charCode- api.jquery.com/event.which
JCM
Estou tentando colocar um ouvinte de eventos importante em uma tabela, mas não funcionou. Existe uma quantidade limitada de tipos de seletores que suportam os principais ouvintes de eventos?
Arman Bimatov
23

É um pouco tarde, mas as Teclas de Atalho têm um bug muito importante que faz com que os eventos sejam executados várias vezes se você anexar mais de uma tecla de atalho a um elemento. Basta usar jQuery simples.

$(element).keydown(function(ev) {
    if(ev.which == $.ui.keyCode.DOWN) {
        // your code
        ev.preventDefault();
    }
});
Mackstann
fonte
2
+1 para usar o objeto keycode da interface do usuário. Muito mais fácil de entender do que 37, 38, 39 ou 40. Não sei por que a resposta principal está usando o e.keyCode quando a documentação do jQuery declara explicitamente o uso do e.que explica as diferenças do navegador. Esperamos que esta resposta obtenha mais reconhecimento por fazer o certo.
Nenhum
2
Usar $ .ui.keyCode.DOWN em cada pressionamento de tecla é MUITO MAIS LENTO do que usar o número. Basta adicionar um comentário se estiver preocupado com a clareza, especialmente porque ele deve ser executado sempre que qualquer tecla for pressionada.
Jimbo Jonny
16

Simplesmente combinei os melhores bits das outras respostas:

$(document).keydown(function(e){
    switch(e.which) {
        case $.ui.keyCode.LEFT:
        // your code here
        break;

        case $.ui.keyCode.UP:
        // your code here
        break;

        case $.ui.keyCode.RIGHT:
        // your code here
        break;

        case $.ui.keyCode.DOWN:
        // your code here
        break;

        default: return; // allow other keys to be handled
    }

    // prevent default action (eg. page moving up/down)
    // but consider accessibility (eg. user may want to use keys to choose a radio button)
    e.preventDefault();
});
queimaduras mate
fonte
1
De onde vem a "interface do usuário"? Obtendo "TypeError: $ .ui está indefinido" EDIT - Estava faltando a interface do usuário do JQuery. Foi carregado - não há mais erro.
codificador
3
Aparentemente, ele também está usando jQuery UI, que deve ter essa enumeração. Eu não incluiria a interface do usuário do jQuery apenas para isso, btw.
Jethro Larson
14

Você pode usar o KeyboardJS. Eu escrevi a biblioteca para tarefas como esta.

KeyboardJS.on('up', function() { console.log('up'); });
KeyboardJS.on('down', function() { console.log('down'); });
KeyboardJS.on('left', function() { console.log('right'); });
KeyboardJS.on('right', function() { console.log('left'); });

Faça o checkout da biblioteca aqui => http://robertwhurst.github.com/KeyboardJS/

Robert Hurst
fonte
14

Uma solução concisa usando Javascript simples (obrigado a Sygmoral pelas melhorias sugeridas):

document.onkeydown = function(e) {
    switch (e.keyCode) {
        case 37:
            alert('left');
            break;
        case 39:
            alert('right');
            break;
    }
};

Consulte também https://stackoverflow.com/a/17929007/1397061 .

1 ''
fonte
Provavelmente também vale a pena ligar viadocument.addEventListener('keydown', myFunction);
nathanbirrell 17/17/17
9

Tem certeza de que o jQuery.HotKeys não suporta as teclas de seta? Eu brinquei com a demo deles antes e observei o funcionamento esquerdo, direito, para cima e para baixo quando o testei no IE7, Firefox 3.5.2 e Google Chrome 2.0.172 ...

EDIT : Parece que o jquery.hotkeys foi realocado para o Github: https://github.com/jeresig/jquery.hotkeys

Pandincus
fonte
Eu estava lendo onde dizia que era baseado em outra biblioteca e presumi que a lista de chaves suportadas ainda fosse aplicada.
Alex S
5

Em vez de usar return false;como nos exemplos acima, você pode usar o e.preventDefault();que faz o mesmo, mas é mais fácil de entender e ler.

Gaetan
fonte
4
return false;e e.preventDefault();não são exatamente iguais. Veja stackoverflow.com/a/1357151/607874
Jose Rui Santos
4

Exemplo de js puro com a direita ou a esquerda

        window.addEventListener('keydown', function (e) {
            // go to the right
            if (e.keyCode == 39) {

            }
            // go to the left
            if (e.keyCode == 37) {

            }
        });
Vince Verhoeven
fonte
3

Você pode usar o jQuery bind:

$(window).bind('keydown', function(e){
    if (e.keyCode == 37) {
        console.log('left');
    } else if (e.keyCode == 38) {
        console.log('up');
    } else if (e.keyCode == 39) {
        console.log('right');
    } else if (e.keyCode == 40) {
        console.log('down');
    }
});
Alessandro Pirovano
fonte
2

Você pode verificar se um arrow keyé pressionado por:

$(document).keydown(function(e){
    if (e.keyCode > 36 && e.keyCode < 41) { 
       alert( "arrowkey pressed" );
       return false;
    }
});
suhailvs
fonte
0

impedir seta disponível apenas para qualquer outro objeto SELECT, bem, na verdade eu não tenho tes em outro objeto LOL. mas pode parar o evento de seta na página e no tipo de entrada.

Eu já tento bloquear a seta para a esquerda e para a direita para alterar o valor do objeto SELECT usando "e.preventDefault ()" ou "return false" no evento "kepress" "keydown" e "keyup", mas ele ainda altera o valor do objeto. mas o evento ainda informa que a seta foi pressionada.

phoenixs
fonte
0

Uma robusta biblioteca Javascript para capturar as entradas do teclado e as combinações de teclas inseridas. Não possui dependências.

http://jaywcjlove.github.io/hotkeys/

hotkeys('right,left,up,down', function(e, handler){
    switch(handler.key){
        case "right":console.log('right');break
        case "left":console.log('left');break
        case "up":console.log('up');break
        case "down":console.log('down');break
    }
});
小弟 调 调
fonte
0

Eu vim aqui procurando uma maneira simples de permitir que o usuário, quando focado em uma entrada, use as teclas de seta para marcar com +1 ou -1 uma entrada numérica. Eu nunca encontrei uma boa resposta, mas criei o seguinte código que parece funcionar muito bem - tornando este site amplo agora.

$("input").bind('keydown', function (e) {
    if(e.keyCode == 40 && $.isNumeric($(this).val()) ) {
        $(this).val(parseFloat($(this).val())-1.0);
    } else if(e.keyCode == 38  && $.isNumeric($(this).val()) ) { 
        $(this).val(parseFloat($(this).val())+1.0);
    }
}); 
Scott
fonte
-1

Com café e Jquery

  $(document).on 'keydown', (e) ->
    switch e.which
      when 37 then console.log('left key')
      when 38 then console.log('up key')
      when 39 then console.log('right key')
      when 40 then console.log('down key')
    e.preventDefault()
Philip
fonte