如何通过JavaScript捕获Mac的命令键?

256

如何通过 JavaScript 捕获 Mac 上的 Cmd 键?


6
请使用 https://github.com/madrobby/keymaster。 - Alex Craft
有一个适用于此的 JavaScript 库:keymaster.js(无需像 jQuery 一样的依赖项)。 - bmaeser
12个回答

335

编辑:截至2019年,《e.metaKey》在所有主要浏览器中都得到了支持,详见MDN

请注意,对于Windows操作系统,尽管⊞Windows键被视为“meta”键,但浏览器不会将其作为这样的键来捕获。

这仅适用于MacOS或者其他键盘上的命令键。


Shift/Alt/Ctrl不同,Cmd(“苹果”)键不被视为修饰键 - 相反,您应该监听keydown/keyup事件,并根据event.keyCode记录何时按下并释放键。

不幸的是,这些键码依赖于特定的浏览器:

  • 火狐浏览器: 224
  • 欧朋浏览器: 17
  • WebKit浏览器(Safari/Chrome): 91(左命令键)或93(右命令键)

您可能有兴趣阅读文章:JavaScript Madness: Keyboard Events,我就是从中学到这些知识的。


2
知道Opera现在也属于Webkit类别。我认为只需要监听91、93和224,就可以完成工作了。顺便说一下,17是Ctrl键。旧版Opera没有区分Cmd和Ctrl吗? - Steven Lu
66
看起来在当前版本的Safari、Firefox和Chrome中,event.metaKey像魔术一样运行良好。我认为这是一个更明确的解决方案。 - Miroslav Nedyalkov
9
回应Miroslav的评论,需要注意的是它仅适用于“keydown”事件,而不是“keyup”。 - nachocab
3
回应 @nachocab 的评论:e.key === 'Meta' 对于 keydown 和 keyup 都适用。因此,可以使用它来代替 e.metaKey。 - Heribert
@nachocab,你的评论对我在keydown / keyup事件上卡住了很有帮助。因为我在keypress事件上遇到了问题,不知道出了什么问题)) - PokatilovArt

235

如果您正在处理 keydown 事件,您还可以查看事件中的 event.metaKey 属性。对我来说效果非常好! 您可以在这里尝试


8
在最新版本的 Firefox、Safari 和 Opera 中,.metaKey 确实起作用。在 Chrome 中,.metaKey 在按下 Control 键时触发(而不是 Command 键)。 - Ilya Semenov
1
就此问题而言,你的脚本中 cmd+e 并不能正常工作。Ctrl 键会触发你所使用的 CMD 图标。 - Oscar Godson
1
cmd+e 对我也没有触发事件(在 Chrome 中)。ctrl+e 可以。 - Spencer Williams
28
我认为关键在于(即使在Chrome中),这适用于“keydown”,但不适用于“keyup”或“keypress”。 - philfreo
你可能想要添加一个调用 event.preventDefault() 的方法来防止浏览器和/或操作系统处理命令键。 - bsegraves
显示剩余4条评论

18

我发现在最新版本的Safari(7.0:9537.71)中,如果与另一个键一起按下,则可以检测到命令键。例如,如果您想检测⌘+ x:,则可以检测x键并检查事件的metaKey是否设置为true。例如:

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

仅按下 x 键,将输出120, false。当按下 ⌘+x 时,将输出120, true

这似乎只在 Safari 中有效 - 而不是 Chrome


2017年的现状是什么? - SuperUberDuper

14
基于Ilya的数据,我为支持Mac上的修饰键编写了一个Vanilla JS库:https://github.com/MichaelZelensky/jsLibraries/blob/master/macKeys.js 使用方法很简单,例如:
document.onclick = function (event) {
  if (event.shiftKey || macKeys.shiftKey) {
    //do something interesting
  }
}

已在 Mac 上测试 Chrome、Safari、Firefox 和 Opera。请检查它是否适用于您的设备。


9

keyCodewhich现在已经弃用,因此建议避免在这里使用那些答案。

现在一种方法是使用附带DOM keyupkeypress事件的事件参数上的key属性。以下是如何实现的简单示例:

document.onkeypress = (event) => {
    if (event.key === 'Meta') {
        console.log("Mac or Windows key was pressed!");
    } else {
        console.log("Another key was pressed")
    }
}

这将在Mac上按下cmd键时触发(请参阅MDN文档中的Meta)。需要注意的是,对于支持Windows键的用户键盘/操作系统,它也会触发Windows键的按下。
如果您需要更精细地了解已按下哪个Meta键,可以使用事件上的code属性,它可以是MetaLeftMetaRight,具体取决于哪个物理元键(cmd)被按下。

7
对于使用jQuery的人,有一个出色的插件来处理键盘事件: jQuery 热键插件 我使用以下代码来捕获⌘+S和Ctrl+S:
$(window).bind('keydown.ctrl_s keydown.meta_s', function(event) {
    event.preventDefault();
    // Do something here
});

1
工作得太好了。所有其他按键也被捕获了。 - Felix Rabe
它是否支持跨浏览器? - Adil Malik
1
如果您访问了我的答案中的链接,您就会知道:https://github.com/tzuryby/jquery.hotkeys#jquery-compatibility - Koen.

3

以下是我在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()

2
var element = //the DOM element to listen for the key on.
element.onkeyup = function(e) {
   if(e.metaKey) {
      //command key was pressed
   }
}

var element = document.body; element.onKeyUp = function(e) { if(e.metaKey) { console.log('按下了cmd键') } } - DataGreed

1
使用KeyboardEvent.metaKey: boolean属性
fromEvent(window, 'keydown').pipe(takeUntil(this._ngUnsubscribe)).subscribe(
  (res: KeyboardEvent) => {
    console.log(res.metaKey && res.key === 'Enter');
  }
);

这个例子是关于RxJS的fromEvent,但适用于任何KeyboardEvent。

0
这个节目捕捉了Mac的命令和Windows的Ctrl键。
#Mac命令
$("#my_input").on('change keyup input', function() {
    var e = window.event || e; var key = e.keyCode; if(key == 93) {
        alert("Hello");
}
});

#Windows ctrl

$("#my_input").on('change keyup input', function() {
    var e = window.event || e; var key = e.keyCode; if(key == 17) {
        alert("Hello");
}
});

#两者皆是

$("#my_input").on('change keyup input', function() {
    var e = window.event || e; var key = e.keyCode; if(key == 17 || key == 93) {
        alert("Hello");
}
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接