I have a directive for arrow up
and arrow down
needs. when i copy and page one of the instance of directive only the second one works but not the first one.
how to solve this? please focus on second section "green" colored section on first element and do the up and down
arrow movement.
directive.ts:
import {
Directive,
ElementRef,
HostListener,
AfterViewInit,
} from '@angular/core';
@Directive({
selector: '[appFocuser]',
})
export class AutoFocusDirective implements AfterViewInit {
focusableArray = [];
parent = null;
count = 0;
currentFocus: HTMLElement;
constructor(private el: ElementRef) {}
@HostListener('document:keyup', ['$event']) onKeyup = ($event) => {
if ($event.code === 'ArrowDown') {
if (this.count >= this.focusableArray.length - 1) {
this.count = 0;
this.focusableArray[this.count].focus();
return;
}
this.count ;
this.focusableArray[this.count].focus();
}
if ($event.code === 'ArrowUp') {
if (this.count == 0) {
this.count = this.focusableArray.length - 1;
this.focusableArray[this.count].focus();
return;
}
this.count--;
this.focusableArray[this.count].focus();
}
};
ngAfterViewInit() {
this.parent = this.el.nativeElement;
this.focusableArray = Array.from(
this.parent.querySelectorAll(`[data-focus=true]`)
);
if (this.focusableArray.length) {
this.currentFocus = this.focusableArray[this.count];
this.currentFocus.focus();
}
}
}
CodePudding user response:
In fact, both instances work. One after another. Here
@HostListener('document:keyup', ['$event']) onKeyup = ($event) => {
you're listening to the keyup event on the whole document. Every instance of AutoFocusDirective
catches it, all handlers are executed, presumably in the order of the directives' initialization (probably). The first one assigns focus somewhere (you even see a flash of that). Then the second one does the same, stealing the focus.
One solution would be to instead of listening on document:keyup
, listen on keyup
.
CodePudding user response:
It is because only one element in a page can be focused. You must put both section
parts in another element and give the appFocuser
directive to that element.