コントローラーにキーの組み合わせを監視させようとしています。議論のために、次のように言いましょう: up up down down left right left right b a. ユーザーが現在ページ内のどこにいるかに関係なく、これらを探すために角度を付けるにはどうすればよいですか?
7 に答える
これを行うにはng-keydownを使用できるようです。
これが動作中の plunkerです。
このサンプルでは、 にバインド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)">
Backspace キー (Mac) と Del キー (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');
}
};
このプランカーをチェックしてください。簡単な「2 UP キーストロークを続けて」のシナリオを実装しました。
プレーンなjQueryでそれを行い、イベントを$rootScope.$broadcast
.
jQuery コードを Angularrun
コールバックに登録します (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
キーストロークごとにa を発生させます。本当に必要なのは、$digest
何らかの形で UI を更新する必要があるときに、シーケンスが入力されたときだけです。
編集
実際の jQuery 依存関係を削除する方法についてのコメントを参照してください。
これが私の見解です:
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";
}
});
});
}
}
});
これの違いはディレクティブであるため、これをボディに付けるとページ全体に適用されます。これにより、コードを複数回入力することもできます。
プランカー:
'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()"/>
html の save-enter を変更して、saveEnter in ディレクティブの名前を変更できます。
「vm.saveTitle()」は、やりたいことです。