Como capturar a chave de comando de um Mac via JavaScript?

Respostas:

238

EDIT: a partir de 2019, e.metaKeyé suportado em todos os principais navegadores conforme o MDN .

Observe que no Windows, embora a ⊞ Windowschave seja considerada a chave "meta", ela não será capturada pelos navegadores como tal.

Isso é apenas para a chave de comando no MacOS / teclados.


Diferentemente de Shift/ Alt/ Ctrl, a Cmdtecla (“Apple”) não é considerada uma tecla modificadora - em vez disso, você deve ouvir keydown/ keyupe gravar quando uma tecla é pressionada e depois pressionada com base em event.keyCode.

Infelizmente, esses códigos-chave dependem do navegador:

  • Raposa de fogo: 224
  • Ópera: 17
  • Navegadores WebKit (Safari / Chrome): 91(Comando à Esquerda) ou 93(Comando à Direita)

Você pode estar interessado em ler o artigo JavaScript Madness: Keyboard Events , a partir do qual aprendi esse conhecimento.

Ilya Semenov
fonte
2
Saiba que o Opera agora também está na categoria Webkit. Acho que apenas ouvindo 91, 93 e 224, fará o trabalho. 17 é Ctrl, a propósito. O Opera antigo não diferenciava Cmd e Ctrl ??
Steven Lu
56
Parece que event.metaKey funciona nas versões atuais do Safari, Firefox e Chrome como um encanto. IMO é uma solução muito clara.
Miroslav Nedyalkov
5
Em resposta ao comentário de Miroslav, observe que ele funciona apenas em keydowneventos, não keyup.
Nachocab
209

Você também pode olhar para o event.metaKeyatributo no evento se estiver trabalhando com eventos de pressionamento de tecla. Trabalhou maravilhosamente para mim! Você pode tentar aqui .

Ensolarado
fonte
Isso não parece estar definido para mim com o Firefox 4.0.1 no MacOS. Dado que a resposta aceita e a referência vinculada não concordam com o que você disse, acho que essa resposta está incorreta.
21411 Josh Glover
8
.metaKeyde fato funciona nos mais recentes Firefox, Safari e Opera. No Chrome, .metaKeydispara no controle (não no comando).
Ilya Semenov
1
FWIW, cmd + e não funciona para mim no seu script. Ctrl aciona o CMD ícone que você tem
Oscar Godson
1
O cmd + e também não dispara o evento para mim (chrome). ctrl + e faz.
Spencer Williams
23
Acho que o truque (mesmo no Chrome) é que isso funciona para keydownmas NÃO para keyupou keypress.
philfreo
15

Descobri que você pode detectar a chave de comando na versão mais recente do Safari (7.0: 9537.71) se for pressionada em conjunto com outra tecla. Por exemplo, se você quiser detectar ⌘ + x:, poderá detectar a tecla x AND verificar se event.metaKey está definido como true. Por exemplo:

var key = event.keyCode || event.charCode || 0;
console.log(key, event.metaKey);

Ao pressionar x por si só, isso será exibido 120, false. Ao pressionar ⌘ + x, ele exibirá120, true

Isso parece funcionar apenas no Safari - não no Chrome

cryptopay
fonte
qual é o status em 2017?
SuperUberDuper 24/02
13

Baseando-me nos dados de Ilya, escrevi uma biblioteca Vanilla JS para suportar chaves modificadoras no Mac: https://github.com/MichaelZelensky/jsLibraries/blob/master/macKeys.js

Apenas use-o assim, por exemplo:

document.onclick = function (event) {
  if (event.shiftKey || macKeys.shiftKey) {
    //do something interesting
  }
}

Testado no Chrome, Safari, Firefox, Opera no Mac. Por favor, verifique se funciona para você.

Michael Zelensky
fonte
8

Para pessoas que usam jQuery, existe um excelente plugin para lidar com eventos importantes:

Teclas de atalho jQuery no GitHub

Para capturar + Se Ctrl+ Seu estou usando isso:

$(window).bind('keydown.ctrl_s keydown.meta_s', function(event) {
    event.preventDefault();
    // Do something here
});
Koen.
fonte
1
Funciona muito bem. Todos os outros pressionamentos de tecla também são capturados.
Felix Rabe
É compatível com vários navegadores?
Adil Malik
1
Se você tivesse visitado o link na minha resposta, saberia: github.com/tzuryby/jquery.hotkeys#jquery-compatibility
Koen.
3

Aqui está como eu fiz isso no AngularJS

app = angular.module('MM_Graph')

class Keyboard
  constructor: ($injector)->
    @.$injector  = $injector
    @.$window    = @.$injector.get('$window')                             # get reference to $window and $rootScope objects
    @.$rootScope = @.$injector.get('$rootScope')

  on_Key_Down:($event)=>
    @.$rootScope.$broadcast 'keydown', $event                             # broadcast a global keydown event

    if $event.code is 'KeyS' and ($event.ctrlKey or $event.metaKey)       # detect S key pressed and either OSX Command or Window's Control keys pressed
      @.$rootScope.$broadcast '', $event                                  # broadcast keyup_CtrS event
     #$event.preventDefault()                                             # this should be used by the event listeners to prevent default browser behaviour

  setup_Hooks: ()=>
    angular.element(@.$window).bind "keydown", @.on_Key_Down              # hook keydown event in window (only called once per app load)
    @

app.service 'keyboard', ($injector)=>
  return new Keyboard($injector).setup_Hooks()
Dinis Cruz
fonte