AngularJS - 同时按下多个按键

3

我有以下代码,用于在Angular中捕获按键操作:$broadcast

$document.bind('keypress', function(event) {
    var key = event.which;
    $rootScope.$broadcast('keypress', event);
    $rootScope.$broadcast('keypress:' + key, event);
});

我用$on进行监听。

然而,我想要检测当两个按键同时按下时,比如同时按下enters(不是一个接着一个的组合)。

最好的方法是什么?

编辑

我的想法是这样的:

var keys = [];
$document.bind('keydown', function(event) {
    keys[event.which] = true;
});
$document.bind('keyup', function(event) {
    delete keys[event.which];
});

$document.bind('keypress', function(event) {
    var key = event.which;
    var keysPressed = [];
    angular.forEach(keys, function(value, key) {
        keysPressed += 'keypress:' + key;
    });
    $rootScope.$broadcast('keypress', event);
    $rootScope.$broadcast(keysPressed, event);
});

如果我有多个按键,则创建正确的$broadcast。然而,问题在于现在顺序很重要(即,如果我先按a,然后按enter,那么$broadcast就是keypress:58keypress:13,如果我按另一种方式,我会得到keypress:13keypress:58)。

4个回答

6

我认为广播(Broadcast)被过度使用了。也许可以使用自定义指令(custom directive)?以下是用户按下 Shift+Tab 触发事件的示例:

<input on-shift-tab="prevStep($event,'email')" />

app.directive('onShiftTab', function() {
return function(scope, element, attrs) {
    var map = {9: false, 16: false};

    element.on("keydown", function(event) {
        if (event.which in map) {
            map[event.which] = true;
            if (map[9] && map[16]) {
                scope.$apply(function(){
                    scope.$eval(attrs.onShiftTab, {'$event': event});
                });
                event.preventDefault();
            }
        }
    });
    element.on("keyup", function(event) {
        if (event.which in map) {
            map[event.keyCode] = false;
        }
    });
};
})

2
这个问题的jQuery答案解决得相当有效,以下是一些Angular特定的方法: 讨论中的一个plunker,当两次按上箭头时触发事件: 上面的示例能够实现与jQuery答案相同的效果,但仅使用一个keyup事件侦听器而不是keyup和keydown。还有一个很好的$broadcast用于触发另一个$on事件:
var upHitOnce = false;

$(document).keyup(function(event) {
    if (event.which == 38) {
      if (upHitOnce) {
        $rootScope.$broadcast('DoubleUpFired');
        $rootScope.$apply();
        upHitOnce = false;
      } else {
        upHitOnce = true;
      }
    } else {
      upHitOnce = false;
    }
  });

检测同时按下的键盘按键,例如ctrl+r,需要更多步骤;以下是一个包含Angular示例的jsfiddle:


我不想要组合键。上面的链接是如果您按下“a”,然后再按下“b”。我想在同时按下“a”和“b”时启动某些操作。 - Kousha
最后一个示例包含一项用于管理同时按键的服务:http://jsfiddle.net/firehist/nzUBg/这是我找到的全部,如果我有更多发现会及时更新。只是想帮忙! - quetzaluz
上一个 jsfiddle 很好,我在我的项目中使用了它来处理键盘组合!谢谢! - Mario
当我在JSFiddle中创建一个键组合时,如何创建一个包含数字键盘和常规数字的组合,并与alt键一起按下?我希望这个组合可以在网页上切换手风琴选项卡。 - Mario

1

有一个适用于AngularJS的模块可以完成这种捕获操作,并且非常简单易用:angularHotkeys

以下是在您的控制器中使用的示例代码:

hotkeys.add({
  combo: 'return+s',
  description: 'Shortcut description...',
  callback: function() {
    // your code here
  }
});

0

对于修改键(Ctrl、Alt、Shift),因为有event.ctrlKey、event.altKey、event.shiftKey,所以更简单。但对于非修改键,你应该使用类似这个问题在jQuery中检测单个按键事件上的多个按键的方法:

var map = {68: false, 69: false, 86: false};

$(document).keydown(function(e) {
    if (e.keyCode in map) {
        map[e.keyCode] = true;
        if (map[68] && map[69] && map[86]) {
            // FIRE EVENT
        }
    }
}).keyup(function(e) {
    if (e.keyCode in map) {
        map[e.keyCode] = false;
    }
});

是的,我正在考虑这个。但我想把它做成一个服务,并使其在我注入它的任何地方都可用。我稍微修改了我的问题。 - Kousha

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