您正在将keydown
处理程序附加到每个元素的文档。我认为这stopPropagation()
不会有任何好处,因为这两个处理程序位于同一个元素上,并且它不会从文档向上传播,但两者仍然会触发。
我建议重新评估你是如何接近它的。您只希望具有焦点类的元素对其选项进行评估,那么为什么不使用您的指令将所有这些元素包装在一个元素中,让它只听一次并选择要操作的元素。
(笨蛋)
<div key-mapped="">
<!-- children will apply key map of element with focus class -->
<div id="div1" class="focus" key-map="{
40: '#div2'
}">Hello</div>
指示:
}).directive('keyMapped', function($rootScope) {
return {
restrict: 'A',
link: function(scope, element, attr) {
angular.element(document).bind('keydown', function(event) {
var target = $(element).find('.focus');
console.log('target: ' + target);
var options = scope.$eval(target.attr('key-map'));
- - 编辑 - -
有人让我知道这是否不是一个好习惯,但是您始终可以将事件处理程序放在指令对象上,并确保它只设置一次,并将自定义事件发送到您绑定到您的“焦点”类的元素链接功能。
(笨蛋)
}).directive('keyMap', function($rootScope) {
var dir = {
onKeydown: function(event) {
var element = document.querySelector('.focus');
var newEvent = new CustomEvent("keyMapKeydown", {
detail: { keyCode: event.keyCode },
bubbles: false,
cancelable: true
});
element.dispatchEvent(newEvent);
},
registered: false, // ensure we only listen to keydown once
restrict: 'A',
link: function(scope, element, attr) {
// register listener only if not already registered
if (!dir.registered) {
dir.registered = true;
angular.element(document).bind('keydown', dir.onKeydown);
}
var options = scope.$eval(attr.keyMap);
// listen for custom event which will be dispatched only to the
// element that has the 'focus' class
element.bind('keyMapKeydown', function(event) {
var keyCode = event.detail.keyCode;
if (options && (keyCode in options)) {
element.removeClass('focus');
angular.element(document.querySelector(options[keyCode])).addClass('focus');
event.stopPropagation();
}
});
}
};