使用 HostListener 按 ArrowDown 和 ArrowUp 时焦点不起作用
Focus does not work when pressing ArrowDown and ArrowUp with HostListener
我正在寻找一种在每个 div 元素上使用 ArrowUp 和 ArrowDown 键 focus/highlight 的方法。 div 元素中的 tabindex 为 0 时,下拉列表中的第一个值会获得突出显示的边框,但仍未被选中,并且不确定如何使用 tabIndex 通过 arrowdown 和 arrowup 遍历所有值。我有以下组件和 html 文件。任何帮助将不胜感激。
HTML
<div class="input">
<input type="text" #input [value]="value" >
<div *ngIf="values">
<div *ngFor="let value of values; let i = index">
<div #item tabindex="i">{{value}}</div>
</div>
</div>
TS
@HostListener('window:keydown', ['$event']) keyEvent(event: KeyboardEvent) {
if (event.key == 'ArrowDown') {
this.item.nativeElement.focus();
} else if (event.key == 'ArrowUp') {
this.item.nativeElement.focus();
} else {
//update
}
}
在 you has a method, in this another SO中可以作为“灵感”
嗯,用上一个。这个想法是有一个指令,它有三个变量 prev、self 和 next
@Directive({
selector: "[next-tab]"
})
export class NextTabDirective {
self: any;
next: any;
prev: any;
@HostListener("keydown.arrowup", ["$event"])
onUp(event: KeyboardEvent) {
if (this.prev && this.prev.focus) {
this.prev.focus();
this.prev.select();
event.preventDefault();
return false;
}
}
@HostListener("keydown.arrowdown", ["$event"])
onDown(event: KeyboardEvent) {
if (this.next && this.next.focus) {
this.next.focus();
this.next.select();
event.preventDefault();
return false;
}
}
constructor(private control: ElementRef) {
this.self = control.nativeElement;
}
}
好吧,我们将创建一个考虑内部“下一个选项卡”的新指令
export class ManageArrowDirective implements AfterViewInit {
@ContentChildren(NextTabDirective) controls: QueryList<NextTabDirective>;
ngAfterViewInit() {
const controls=this.controls.toArray()
controls.forEach((x, index) => {
x.prev = index ? controls[index - 1].self : null;
x.next =
index < controls.length - 1 ? controls[index + 1].self : null;
});
this.controls.changes.subscribe(ctrls => {
const controls=ctrls.toArray();
controls.forEach((x, index) => {
x.prev = index ? controls[index - 1].self : null;
x.next =
index < controls.length - 1 ? controls[index + 1].self : null;
});
});
}
}
您使用
<div mannage-arrow>
<input next-tab ...>
<input next-tab ...>
</div>
指令“NextTabDirective”可以应用于ngControls,所以我们可以控制它是否被禁用
我们开始了!
首先在我们指令的构造函数中注入 ngControl 作为 public
constructor(private control: ElementRef,@Optional()public ngControl:NgControl) {
this.self = control.nativeElement;
}
然后,实现一些复杂的指令来控制禁用的控件
export class ManageControlDirective implements AfterViewInit {
@ContentChildren(NgControlDirective,{descendants:true}) controls: QueryList<NgControlDirective>;
ngAfterViewInit() {
this.rearrange();
this.controls.changes.subscribe(ctrls => {
this.rearrange(ctrls.toArray())
});
}
rearrange(controls:NgControlDirective[]=null)
{
setTimeout(()=>{
controls=controls||this.controls.toArray()
controls.forEach((x, index) => {
x.prev = this.getPrevControlEnabled(index,controls)
x.next = this.getNextControlEnabled(index,controls)
});
})
}
getPrevControlEnabled(index,controls:NgControlDirective[]){
if (index)
return controls[index-1].ngControl.enabled?controls[index-1].self:this.getPrevControlEnabled(index-1,controls)
return null;
}
getNextControlEnabled(index,controls:NgControlDirective[]){
if (index<controls.length-1)
return controls[index+1].ngControl.enabled?controls[index+1].self:this.getNextControlEnabled(index+1,controls)
return null;
}
}
中查看这两个示例的示例
我正在寻找一种在每个 div 元素上使用 ArrowUp 和 ArrowDown 键 focus/highlight 的方法。 div 元素中的 tabindex 为 0 时,下拉列表中的第一个值会获得突出显示的边框,但仍未被选中,并且不确定如何使用 tabIndex 通过 arrowdown 和 arrowup 遍历所有值。我有以下组件和 html 文件。任何帮助将不胜感激。
HTML
<div class="input">
<input type="text" #input [value]="value" >
<div *ngIf="values">
<div *ngFor="let value of values; let i = index">
<div #item tabindex="i">{{value}}</div>
</div>
</div>
TS
@HostListener('window:keydown', ['$event']) keyEvent(event: KeyboardEvent) {
if (event.key == 'ArrowDown') {
this.item.nativeElement.focus();
} else if (event.key == 'ArrowUp') {
this.item.nativeElement.focus();
} else {
//update
}
}
在
嗯,用上一个。这个想法是有一个指令,它有三个变量 prev、self 和 next
@Directive({
selector: "[next-tab]"
})
export class NextTabDirective {
self: any;
next: any;
prev: any;
@HostListener("keydown.arrowup", ["$event"])
onUp(event: KeyboardEvent) {
if (this.prev && this.prev.focus) {
this.prev.focus();
this.prev.select();
event.preventDefault();
return false;
}
}
@HostListener("keydown.arrowdown", ["$event"])
onDown(event: KeyboardEvent) {
if (this.next && this.next.focus) {
this.next.focus();
this.next.select();
event.preventDefault();
return false;
}
}
constructor(private control: ElementRef) {
this.self = control.nativeElement;
}
}
好吧,我们将创建一个考虑内部“下一个选项卡”的新指令
export class ManageArrowDirective implements AfterViewInit {
@ContentChildren(NextTabDirective) controls: QueryList<NextTabDirective>;
ngAfterViewInit() {
const controls=this.controls.toArray()
controls.forEach((x, index) => {
x.prev = index ? controls[index - 1].self : null;
x.next =
index < controls.length - 1 ? controls[index + 1].self : null;
});
this.controls.changes.subscribe(ctrls => {
const controls=ctrls.toArray();
controls.forEach((x, index) => {
x.prev = index ? controls[index - 1].self : null;
x.next =
index < controls.length - 1 ? controls[index + 1].self : null;
});
});
}
}
您使用
<div mannage-arrow>
<input next-tab ...>
<input next-tab ...>
</div>
指令“NextTabDirective”可以应用于ngControls,所以我们可以控制它是否被禁用
我们开始了!
首先在我们指令的构造函数中注入 ngControl 作为 public
constructor(private control: ElementRef,@Optional()public ngControl:NgControl) {
this.self = control.nativeElement;
}
然后,实现一些复杂的指令来控制禁用的控件
export class ManageControlDirective implements AfterViewInit {
@ContentChildren(NgControlDirective,{descendants:true}) controls: QueryList<NgControlDirective>;
ngAfterViewInit() {
this.rearrange();
this.controls.changes.subscribe(ctrls => {
this.rearrange(ctrls.toArray())
});
}
rearrange(controls:NgControlDirective[]=null)
{
setTimeout(()=>{
controls=controls||this.controls.toArray()
controls.forEach((x, index) => {
x.prev = this.getPrevControlEnabled(index,controls)
x.next = this.getNextControlEnabled(index,controls)
});
})
}
getPrevControlEnabled(index,controls:NgControlDirective[]){
if (index)
return controls[index-1].ngControl.enabled?controls[index-1].self:this.getPrevControlEnabled(index-1,controls)
return null;
}
getNextControlEnabled(index,controls:NgControlDirective[]){
if (index<controls.length-1)
return controls[index+1].ngControl.enabled?controls[index+1].self:this.getNextControlEnabled(index+1,controls)
return null;
}
}
中查看这两个示例的示例