¿Cómo se captura la tecla de comando de una Mac a través de JavaScript?

Respuestas:

238

EDITAR: a partir de 2019, e.metaKeyes compatible con todos los principales navegadores según el MDN .

Tenga en cuenta que en Windows, aunque la ⊞ Windowsclave se considera la clave "meta", los navegadores no la capturarán como tal.

Esto es solo para la tecla de comando en MacOS / teclados.


A diferencia de Shift/ Alt/ Ctrl, la Cmdtecla ("Apple") no se considera una tecla modificadora; en cambio, debe escuchar y keydown/ keyupo grabar cuando se presiona una tecla y luego se presiona según event.keyCode.

Desafortunadamente, estos códigos clave dependen del navegador:

  • Firefox 224
  • Ópera: 17
  • Navegadores WebKit (Safari / Chrome): 91(Comando izquierdo) o 93(Comando derecho)

Puede que le interese leer el artículo JavaScript Madness: Keyboard Events , del que aprendí ese conocimiento.

Ilya Semenov
fuente
2
Sepa que Opera ahora también está bajo la categoría de Webkit. Creo que solo escuchar 91, 93 y 224 hará el trabajo. 17 es Ctrl, por cierto. ¿La antigua Opera no diferenciaba Cmd y Ctrl?
Steven Lu
56
Parece que event.metaKey funciona de maravilla en las versiones actuales de Safari, Firefox y Chrome. En mi opinión, es una solución muy clara.
Miroslav Nedyalkov
55
En respuesta al comentario de Miroslav, solo tenga en cuenta que solo funciona en keydowneventos, no keyup.
nachocab
209

También puede ver el event.metaKeyatributo en el evento si está trabajando con eventos keydown. ¡Funcionó maravillosamente para mí! Puedes probarlo aquí .

Soleado
fuente
Eso no parece estar configurado para mí con Firefox 4.0.1 en MacOS. Dado que la respuesta aceptada y la referencia vinculada no están de acuerdo con lo que ha dicho también, creo que esta respuesta es incorrecta.
Josh Glover
8
.metaKeyde hecho funciona en los últimos Firefox, Safari y Opera. En Chrome, se .metaKeydispara en Control (no en Command).
Ilya Semenov el
1
FWIW, cmd + e no funciona para mí en tu script. Ctrl activa el icono de CMD que tienes
Oscar Godson
1
cmd + e tampoco activa el evento para mí (chrome). ctrl + e hace.
Spencer Williams
23
Creo que el truco (incluso en Chrome) es que esto funciona keydownpero NO para keyupo keypress.
philfreo
15

Descubrí que puede detectar la tecla de comando en la última versión de Safari (7.0: 9537.71) si se presiona junto con otra tecla. Por ejemplo, si desea detectar ⌘ + x :, puede detectar la tecla x Y verificar si event.metaKey está establecido en verdadero. Por ejemplo:

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

Al presionar x por sí mismo, esto generará 120, false. Al presionar ⌘ + x, saldrá120, true

Esto solo parece funcionar en Safari, no en Chrome

criptopago
fuente
¿Cuál es el estado en 2017?
SuperUberDuper
13

Basándome en los datos de Ilya, escribí una biblioteca Vanilla JS para admitir teclas modificadoras en Mac: https://github.com/MichaelZelensky/jsLibraries/blob/master/macKeys.js

Solo utilízalo así, por ejemplo:

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

Probado en Chrome, Safari, Firefox, Opera en Mac. Por favor, compruebe si funciona para usted.

Michael Zelensky
fuente
8

Para las personas que usan jQuery, hay un complemento excelente para manejar eventos clave:

teclas de acceso rápido jQuery en GitHub

Para capturar + Sy Ctrl+ Sestoy usando esto:

$(window).bind('keydown.ctrl_s keydown.meta_s', function(event) {
    event.preventDefault();
    // Do something here
});
Koen
fuente
1
Funciona muy bien Todas las demás pulsaciones de teclas también se capturan.
Felix Rabe
¿Es compatible con el navegador cruzado?
Adil Malik
1
Si visitó el enlace en mi respuesta, habría sabido: github.com/tzuryby/jquery.hotkeys#jquery-compatibility
Koen.
3

Así es como lo hice en 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
fuente