我正试图让我的控制器观察组合键。为了论证,让我们说:向上向下左下左右b a。无论用户当前在页面中的哪个位置,我如何获得角度以查找这些内容?
答案 0 :(得分:11)
您似乎可以使用ng-keydown执行此操作。
对于此示例,我只是将ng-keydown
绑定到<body>
。适用于全局捕获所有键盘事件。
正如@charlietfl所指出的那样,ng-keydown
注册了很多键盘事件,所以要使这个可用起来会有很多工作。例如,如果您尝试收听组合(例如ctrl
+ r
),则ctrl
键会多次注册。
<强> JS:强>
var myApp = angular.module('myApp', []);
myApp.controller('Ctrl', function($scope) {
$scope.keyBuffer = [];
function arrays_equal(a,b) { return !(a<b || b<a); }
$scope.down = function(e) {
$scope.keyBuffer.push(e.keyCode);
var upUp = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65];
if (arrays_equal(upUp, $scope.keyBuffer)) {
alert('thats it!');
}
};
});
<强> HTML:强>
<body ng-controller="Ctrl" ng-keydown="down($event)">
答案 1 :(得分:4)
我正在使用不同的方式来做到这一点。
$scope.keyboard = {
buffer: [],
detectCombination: function() {
var codes = {};
this.buffer.forEach(function(code) {
codes['key_' + code] = 1;
});
if ((codes.key_91 || codes.key_93) && codes.key_8) {
// I'm looking for 'command + delete'
}
},
keydown: function($event) {
this.buffer.push($event.keyCode);
this.detectCombination();
},
keyup: function($event, week) {
this.buffer = [];
}
};
答案 2 :(得分:2)
检测Backspace-Key(Mac)和Del-Key(PC):
<body ng-controller="Ctrl" ng-keydown="keyDown($event)">..<body>
$scope.keyDown = function(value){
if(value.keyCode == 46 || value.keyCode == 8) {
//alert('Delete Key Pressed');
}
};
答案 3 :(得分:1)
这都是未经测试的,但您可以使用ng-keypress
<body ng-keypress="logKeys($rootScope,$event)">...</body>
调用类似的函数:
appCtrl.$scope.logKeys = function($rootScope,$event){
$rootScope.keyLog.shift(); // Remove First Item of Array
$rootScope.keyLog.push($event.keyCode); // Adds new key press to end of Array
if($scope.$rootScope.keyLog[0] !== 38) { return false; } // 38 == up key
if($scope.$rootScope.keyLog[1] !== 38) { return false; }
if($scope.$rootScope.keyLog[2] !== 40) { return false; } // 40 = down key
if($scope.$rootScope.keyLog[3] !== 40) { return false; }
if($scope.$rootScope.keyLog[4] !== 27) { return false; } // 37 = left key
if($scope.$rootScope.keyLog[5] !== 39) { return false; } // 39 = right key
if($scope.$rootScope.keyLog[6] !== 37) { return false; }
if($scope.$rootScope.keyLog[7] !== 39) { return false; }
if($scope.$rootScope.keyLog[8] !== 65) { return false; } // 65 = a
if($scope.$rootScope.keyLog[9] !== 66) { return false; } // 66 = b
$rootScope.doThisWhenAllKeysPressed(); // Got this far, must all match!
return true;
}
在输入字段之外,我认为ng-keypress不起作用,但来自angular-ui的按键可能。
我确定应该有一个阵列差异功能,但特定的呼叫现在就避开了我。
答案 4 :(得分:0)
结帐this plunker。我已经实现了一个简单的“连续2次击键”场景。
您可以在纯jQuery中执行此操作,并使用$rootScope.$broadcast
。
注册jQuery代码和Angular run
回调(保证angular已经引导):
app.run(function($rootScope) {
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;
}
});
});
然后任何控制器都可以监听此事件,如:
$scope.$on('DoubleUpFired', function() {
$scope.fired = true;
});
将ng-keydown
操作回调绑定到body
是可以的,但有一个小缺点。它会在每次击键时触发$digest
。只有在您以某种方式需要更新UI时输入序列时,您真正想要的是$digest
。
请参阅有关如何删除实际jQuery依赖关系的注释。
答案 5 :(得分:0)
这是我的看法:
var app = angular.module('contra', []);
app.directive('code', function () {
function codeState() {
this.currentState = 0;
this.keys = [38, 38, 40, 40, 37, 39, 37, 39, 66, 65];
this.keyPressed = function (key) {
if (this.keys[this.currentState] == key) {
this.currentState++;
if (this.currentState == this.keys.length) {
this.currentState = 0;
return true;
}
} else {
this.currentState = 0;
}
return false;
};
};
return {
restrict: 'A',
link: function (scope, element, attrs) {
var cs = new codeState();
scope.isValid = "NO";
element.bind("keydown", function (event) {
scope.$apply(function () {
if (cs.keyPressed(event.which)) {
scope.isValid = "YES";
console.log("CODE ENTERED");
} else {
scope.isValid = "NO";
}
});
});
}
}
});
这有什么不同,这是一个指令,所以如果你把它贴在身上,它将适用于整个页面。这也允许多次输入代码。
Plunkr:
答案 6 :(得分:0)
如果您尝试'ctrl + s'或'commond + s'(更改commondKey)进行保存,也许可以像这样使用:
指令:
(function () {
'use strict';
var lastKey = 0;
//var commondKey = 17;
var commondKey = 91;
angular
.module('xinshu')
.directive('saveEnter', function () {
return function (scope, element, attrs) {
element.bind("keydown", function (event) {
if (event.which != commondKey && event.which != 83) {
lastKey = 0;
}
if (lastKey == commondKey && event.which == 83) {
scope.$apply(function () {
scope.$eval(attrs.saveEnter);
});
event.preventDefault();
}
lastKey = event.which;
});
};
});
})();
元素:
<input id="title" save-enter="vm.saveTitle()"/>
您可以在指令中重命名saveEnter,并在html中更改save-enter。
'vm.saveTitle()'是你想做的事情。