Jak przechwycić klawisz polecenia Maca za pomocą JavaScript?

Odpowiedzi:

238

EDYCJA: od 2019 e.metaKeyjest obsługiwana we wszystkich głównych przeglądarkach zgodnie z MDN .

Zauważ, że w systemie Windows, chociaż ⊞ Windowsklucz jest uważany za klucz „meta”, nie zostanie przechwycony przez przeglądarki jako taki.

Dotyczy to tylko klawisza Command na MacOS / klawiaturach.


W przeciwieństwie do Shift/ Alt/ Ctrl, Cmdklawisz („Apple”) nie jest uważany za klawisz modyfikujący - zamiast tego należy nasłuchiwać keydown/ keyupi nagrywać, gdy klawisz jest naciskany, a następnie wciskany event.keyCode.

Niestety te kluczowe kody zależą od przeglądarki:

  • Firefox: 224
  • Opera: 17
  • Przeglądarki WebKit (Safari / Chrome): 91(Lewe polecenie) lub 93(Prawe polecenie)

Możesz być zainteresowany przeczytaniem artykułu JavaScript Madness: Keyboard Events , z którego dowiedziałem się tej wiedzy.

Ilya Semenov
źródło
2
Wiedz, że Opera jest teraz również w kategorii Webkit. Myślę, że po prostu nasłuchiwanie 91, 93 i 224 załatwi sprawę. Nawiasem mówiąc, 17 to Ctrl. Czy stara Opera nie rozróżnia Cmd i Ctrl?
Steven Lu
56
Wygląda na to, że event.metaKey działa w obecnych wersjach Safari, Firefox i Chrome jak marzenie. IMO to bardzo jasne rozwiązanie.
Miroslav Nedyalkov
5
W odpowiedzi na komentarz Miroslava, wystarczy zauważyć, że działa on tylko na keydownwydarzeniach, a nie keyup.
nachocab
209

Możesz również spojrzeć na event.metaKeyatrybut w zdarzeniu, jeśli pracujesz ze zdarzeniami keydown. U mnie zadziałało cudownie! Możesz spróbować tutaj .

Słoneczny
źródło
Wydaje się, że nie jest to ustawione dla mnie w przeglądarce Firefox 4.0.1 na MacOS. Biorąc pod uwagę, że zaakceptowana odpowiedź i powiązane odniesienie nie zgadzają się z tym, co powiedziałeś, myślę, że ta odpowiedź jest nieprawidłowa.
Josh Glover
8
.metaKeyrzeczywiście działa w najnowszych przeglądarkach Firefox, Safari i Opera. W przeglądarce Chrome .metaKeyuruchamia się na Control (nie na Command).
Ilya Semenov
1
FWIW, cmd + e nie działa dla mnie w twoim skrypcie. Ctrl uruchamia ikonę CMD, którą masz
Oscar Godson
1
cmd + e również nie uruchamia zdarzenia dla mnie (chrome). ctrl + e tak.
Spencer Williams
23
Myślę, że sztuczka (nawet w Chrome) polega na tym, że to działa, keydownale NIE w przypadku keyuplub keypress.
philfreo
15

Odkryłem, że możesz wykryć klawisz polecenia w najnowszej wersji Safari (7.0: 9537.71), jeśli zostanie naciśnięty w połączeniu z innym klawiszem. Na przykład, jeśli chcesz wykryć ⌘ + x :, możesz wykryć klawisz x ORAZ sprawdzić, czy event.metaKey ma wartość true. Na przykład:

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

Po samodzielnym naciśnięciu x spowoduje to wyświetlenie 120, false. Po naciśnięciu ⌘ + x zostanie wyświetlone120, true

Wydaje się, że działa to tylko w Safari - nie w Chrome

cryptopay
źródło
jaki jest stan w 2017 roku?
SuperUberDuper
13

Bazując na danych Ilya, napisałem bibliotekę Vanilla JS do obsługi klawiszy modyfikujących na Macu: https://github.com/MichaelZelensky/jsLibraries/blob/master/macKeys.js

Po prostu użyj tego w ten sposób, np:

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

Przetestowano w Chrome, Safari, Firefox, Opera na Macu. Sprawdź, czy to działa dla Ciebie.

Michael Zelensky
źródło
8

Dla osób używających jQuery jest doskonała wtyczka do obsługi kluczowych zdarzeń:

Skróty klawiszowe jQuery w serwisie GitHub

Do przechwytywania + Si Ctrl+ Sużywam tego:

$(window).bind('keydown.ctrl_s keydown.meta_s', function(event) {
    event.preventDefault();
    // Do something here
});
Koen.
źródło
1
Działa zbyt dobrze. Wszystkie inne naciśnięcia klawiszy również zostaną przechwycone.
Felix Rabe
Czy obsługuje wiele przeglądarek?
Adil Malik
1
Gdybyś odwiedził link w mojej odpowiedzi, wiedziałbyś: github.com/tzuryby/jquery.hotkeys#jquery-compatibility
Koen.
3

Oto jak to zrobiłem w 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
źródło