您正在爲文檔中的每個元素附加處理程序。我不認爲stopPropagation()
會做任何好處,因爲這兩個處理程序在同一個元素上,它不會從文檔中傳播出去,但兩者仍會觸發。
我建議重新評估你如何接近它。你只希望具有焦點類的元素擁有它的選項評估,那麼爲什麼不用你的指令將所有這些元素包含在一個元素中,並讓它只聽一次並選擇要處理的元素。
(plunker)
<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'));
---- ----編輯
有人讓我知道,如果它不是一個很好的做法,但您始終可以將事件處理程序放在您的指令對象上,並確保它只設置一次並將自定義事件發送到鏈接函數中綁定的「焦點」類的元素。
(plunker)
}).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();
}
});
}
};
是否有可能僅附加一個事件偵聽器keydown事件不使用包裝「keyMapped」指令? – Kay